#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "codegen.h"
#include "db.h"
#include "defines.h"
#include "exclude.h"
#include "expr.h"
#include "func_iter.h"
#include "func_unit.h"
#include "instance.h"
#include "line.h"
#include "link.h"
#include "obfuscate.h"
#include "ovl.h"
#include "report.h"
#include "util.h"
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. | |
static bool | line_display_instance_summary (FILE *ofile, const char *name, int hits, int total) |
static bool | line_instance_summary (FILE *ofile, funit_inst *root, char *parent_inst, int *hits, int *total) |
static bool | line_display_funit_summary (FILE *ofile, const char *name, const char *fname, int hits, int total) |
static bool | line_funit_summary (FILE *ofile, funit_link *head, int *hits, int *total) |
static void | line_display_verbose (FILE *ofile, func_unit *funit, rpt_type rtype) |
static void | line_instance_verbose (FILE *ofile, funit_inst *root, char *parent_inst) |
static void | line_funit_verbose (FILE *ofile, funit_link *head) |
void | line_report (FILE *ofile, bool verbose) |
Generates report output for line coverage. | |
Variables | |
db ** | db_list |
unsigned int | curr_db |
bool | report_covered |
unsigned int | report_comb_depth |
bool | report_instance |
isuppl | info_suppl |
bool | flag_suppress_empty_funits |
bool | flag_output_exclusion_ids |
bool | report_exclusions |
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 }
static bool line_display_funit_summary | ( | FILE * | ofile, | |
const char * | name, | |||
const char * | fname, | |||
int | hits, | |||
int | total | |||
) | [static] |
Calculates the percentage and miss information for the given hit and total coverage info and outputs this information in human-readable format to the given output file.
ofile | Pointer to file to output functional unit line summary information to | |
name | Name of functional unit being displayed | |
fname | Filename containing function unit being displayed | |
hits | Number of hits in this functional unit | |
total | Number of total lines in this functional unit |
References calc_miss_percent(), PROFILE, and PROFILE_END.
Referenced by line_funit_summary(), and line_report().
00339 { PROFILE(LINE_DISPLAY_FUNIT_SUMMARY); 00340 00341 float percent; /* Percentage of lines hits */ 00342 int miss; /* Number of lines missed */ 00343 00344 calc_miss_percent( hits, total, &miss, &percent ); 00345 00346 fprintf( ofile, " %-20.20s %-20.20s %5d/%5d/%5d %3.0f%%\n", 00347 name, fname, hits, miss, total, percent ); 00348 00349 PROFILE_END; 00350 00351 return (miss > 0); 00352 00353 }
static bool line_display_instance_summary | ( | FILE * | ofile, | |
const char * | name, | |||
int | hits, | |||
int | total | |||
) | [static] |
Outputs the instance summary information to the given output file.
ofile | Pointer to output file to display information to | |
name | Name of instance to display | |
hits | Number of lines hit in the given instance | |
total | Total number of lines in the given instance |
References calc_miss_percent(), PROFILE, and PROFILE_END.
Referenced by line_instance_summary(), and line_report().
00245 { PROFILE(LINE_DISPLAY_INSTANCE_SUMMARY); 00246 00247 float percent; /* Percentage of lines hits */ 00248 int miss; /* Number of lines missed */ 00249 00250 calc_miss_percent( hits, total, &miss, &percent ); 00251 00252 fprintf( ofile, " %-43.43s %5d/%5d/%5d %3.0f%%\n", 00253 name, hits, miss, total, percent ); 00254 00255 PROFILE_END; 00256 00257 return( miss > 0 ); 00258 00259 }
Displays the lines missed during simulation to standard output from the specified expression list.
ofile | Pointer to file to output results to | |
funit | Pointer to functional unit containing lines to display in verbose format | |
rtype | Specifies the type of lines to output |
References codegen_gen_expr(), db_gen_exclusion_id(), db_get_exclusion_id_size(), 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, FALSE, flag_output_exclusion_ids, free_safe, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), expression_s::id, expression_s::line, expression_s::op, statement_s::part, PROFILE, PROFILE_END, exclude_reason_s::reason, report_covered, report_output_exclusion_reason(), RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, statement_s::suppl, and TRUE.
Referenced by line_funit_verbose(), and line_instance_verbose().
00409 { PROFILE(LINE_DISPLAY_VERBOSE); 00410 00411 statement* stmt; /* Pointer to current statement */ 00412 expression* unexec_exp; /* Pointer to current unexecuted expression */ 00413 char** code; /* Pointer to code string from code generator */ 00414 unsigned int code_depth; /* Depth of code array */ 00415 unsigned int i; /* Loop iterator */ 00416 func_iter fi; /* Functional unit iterator */ 00417 00418 switch( rtype ) { 00419 case RPT_TYPE_HIT : fprintf( ofile, " Hit Lines\n\n" ); break; 00420 case RPT_TYPE_MISS : fprintf( ofile, " Missed Lines\n\n" ); break; 00421 case RPT_TYPE_EXCL : fprintf( ofile, " Excluded Lines\n\n" ); break; 00422 } 00423 00424 /* Initialize functional unit iterator */ 00425 func_iter_init( &fi, funit, TRUE, FALSE ); 00426 00427 /* Display current instance missed lines */ 00428 while( (stmt = func_iter_get_next_statement( &fi )) != NULL ) { 00429 00430 if( (stmt->exp->op != EXP_OP_DELAY) && 00431 (stmt->exp->op != EXP_OP_CASE) && 00432 (stmt->exp->op != EXP_OP_CASEX) && 00433 (stmt->exp->op != EXP_OP_CASEZ) && 00434 (stmt->exp->op != EXP_OP_DEFAULT) && 00435 (stmt->exp->op != EXP_OP_NB_CALL) && 00436 (stmt->exp->op != EXP_OP_FORK) && 00437 (stmt->exp->op != EXP_OP_JOIN) && 00438 (stmt->exp->op != EXP_OP_NOOP) && 00439 (stmt->exp->op != EXP_OP_FOREVER) && 00440 (stmt->exp->op != EXP_OP_RASSIGN) && 00441 (stmt->exp->line != 0) ) { 00442 00443 if( ((((stmt->exp->exec_num > 0) ? 1 : 0) == report_covered) && (stmt->suppl.part.excluded == 0) && (rtype != RPT_TYPE_EXCL)) || 00444 ((stmt->suppl.part.excluded == 1) && (rtype == RPT_TYPE_EXCL)) ) { 00445 00446 unexec_exp = stmt->exp; 00447 00448 codegen_gen_expr( unexec_exp, unexec_exp->op, &code, &code_depth, funit ); 00449 if( flag_output_exclusion_ids && (rtype != RPT_TYPE_HIT) ) { 00450 exclude_reason* er; 00451 fprintf( ofile, " (%s) %7d: %s%s\n", 00452 db_gen_exclusion_id( 'L', unexec_exp->id ), unexec_exp->line, code[0], ((code_depth == 1) ? "" : "...") ); 00453 if( (rtype == RPT_TYPE_EXCL) && ((er = exclude_find_exclude_reason( 'L', unexec_exp->id, funit )) != NULL) ) { 00454 report_output_exclusion_reason( ofile, (22 + (db_get_exclusion_id_size() - 1)), er->reason, TRUE ); 00455 } 00456 } else { 00457 exclude_reason* er; 00458 fprintf( ofile, " %7d: %s%s\n", unexec_exp->line, code[0], ((code_depth == 1) ? "" : "...") ); 00459 if( (rtype == RPT_TYPE_EXCL) && ((er = exclude_find_exclude_reason( 'L', unexec_exp->id, funit )) != NULL) ) { 00460 report_output_exclusion_reason( ofile, 18, er->reason, TRUE ); 00461 } 00462 } 00463 for( i=0; i<code_depth; i++ ) { 00464 free_safe( code[i], (strlen( code[i] ) + 1) ); 00465 } 00466 free_safe( code, (sizeof( char* ) * code_depth) ); 00467 00468 } 00469 00470 } 00471 00472 } 00473 00474 func_iter_dealloc( &fi ); 00475 00476 fprintf( ofile, "\n" ); 00477 00478 PROFILE_END; 00479 00480 }
static bool line_funit_summary | ( | FILE * | ofile, | |
funit_link * | head, | |||
int * | hits, | |||
int * | total | |||
) | [static] |
Iterates through the functional unit list, displaying the line coverage results (summary format) for each functional unit.
ofile | Pointer to file to output results to | |
head | Pointer to head of functional unit list to explore | |
hits | Pointer to accumulated hit information | |
total | Pointer to accumulated total information |
References isuppl_u::assert_ovl, FALSE, func_unit_s::filename, free_safe, funit_link_s::funit, funit_flatten_name(), funit_is_unnamed(), get_basename(), line_display_funit_summary(), statistic_s::line_hit, statistic_s::line_total, funit_link_s::next, obf_file, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, scope_gen_printable(), statistic_s::show, and func_unit_s::stat.
Referenced by line_report().
00367 { PROFILE(LINE_FUNIT_SUMMARY); 00368 00369 bool miss_found = FALSE; /* Set to TRUE if line was found to be missed */ 00370 char* pname; /* Printable version of functional unit name */ 00371 00372 while( head != NULL ) { 00373 00374 /* If this is an assertion module, don't output any further */ 00375 if( head->funit->stat->show && !funit_is_unnamed( head->funit ) && 00376 ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( head->funit )) ) { 00377 00378 /* Get printable version of functional unit name */ 00379 pname = scope_gen_printable( funit_flatten_name( head->funit ) ); 00380 00381 miss_found |= line_display_funit_summary( ofile, pname, get_basename( obf_file( head->funit->filename ) ), head->funit->stat->line_hit, head->funit->stat->line_total ); 00382 00383 /* Update accumulated information */ 00384 *hits += head->funit->stat->line_hit; 00385 *total += head->funit->stat->line_total; 00386 00387 free_safe( pname, (strlen( pname ) + 1) ); 00388 00389 } 00390 00391 head = head->next; 00392 00393 } 00394 00395 PROFILE_END; 00396 00397 return( miss_found ); 00398 00399 }
static void line_funit_verbose | ( | FILE * | ofile, | |
funit_link * | head | |||
) | [static] |
Displays the verbose line coverage results to the specified output stream on a functional unit basis (combining functional units that are instantiated multiple times). The verbose line coverage includes the line numbers (and associated verilog code) and file/functional unit name of the lines that were not hit during simulation.
ofile | Pointer to file to output results to | |
head | Pointer to head of functional unit list to search through |
References func_unit_s::filename, free_safe, funit_link_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, line_display_verbose(), statistic_s::line_excluded, statistic_s::line_hit, statistic_s::line_total, funit_link_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, scope_gen_printable(), func_unit_s::stat, and func_unit_s::type.
Referenced by line_report().
00567 { PROFILE(LINE_FUNIT_VERBOSE); 00568 00569 char* pname; /* Printable version of functional unit name */ 00570 00571 while( head != NULL ) { 00572 00573 if( !funit_is_unnamed( head->funit ) && 00574 (((head->funit->stat->line_hit < head->funit->stat->line_total) && !report_covered) || 00575 ((head->funit->stat->line_hit > 0) && report_covered) || 00576 ((head->funit->stat->line_excluded > 0) && report_exclusions)) ) { 00577 00578 /* Get printable version of functional unit name */ 00579 pname = scope_gen_printable( funit_flatten_name( head->funit ) ); 00580 00581 fprintf( ofile, "\n" ); 00582 switch( head->funit->type ) { 00583 case FUNIT_MODULE : fprintf( ofile, " Module: " ); break; 00584 case FUNIT_ANAMED_BLOCK : 00585 case FUNIT_NAMED_BLOCK : fprintf( ofile, " Named Block: " ); break; 00586 case FUNIT_AFUNCTION : 00587 case FUNIT_FUNCTION : fprintf( ofile, " Function: " ); break; 00588 case FUNIT_ATASK : 00589 case FUNIT_TASK : fprintf( ofile, " Task: " ); break; 00590 default : fprintf( ofile, " UNKNOWN: " ); break; 00591 } 00592 fprintf( ofile, "%s, File: %s\n", pname, obf_file( head->funit->filename ) ); 00593 fprintf( ofile, " -------------------------------------------------------------------------------------------------------------\n" ); 00594 00595 free_safe( pname, (strlen( pname ) + 1) ); 00596 00597 if( ((head->funit->stat->line_hit < head->funit->stat->line_total) && !report_covered) || 00598 ((head->funit->stat->line_hit > 0) && report_covered && (!report_exclusions || (head->funit->stat->line_hit > head->funit->stat->line_excluded))) ) { 00599 line_display_verbose( ofile, head->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) ); 00600 } 00601 if( (head->funit->stat->line_excluded > 0) && report_exclusions ) { 00602 line_display_verbose( ofile, head->funit, RPT_TYPE_EXCL ); 00603 } 00604 00605 } 00606 00607 head = head->next; 00608 00609 } 00610 00611 PROFILE_END; 00612 00613 }
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 }
static bool line_instance_summary | ( | FILE * | ofile, | |
funit_inst * | root, | |||
char * | parent_inst, | |||
int * | hits, | |||
int * | total | |||
) | [static] |
Recursively iterates through the instance tree gathering the total number of lines parsed vs. the total number of lines executed during the course of simulation. The parent node will display its information before calling its children.
ofile | Pointer to file to output results to | |
root | Current node in instance tree | |
parent_inst | Name of parent instance | |
hits | Pointer to accumulated hit information | |
total | Pointer to accumulated total information |
References isuppl_u::assert_ovl, funit_inst_s::child_head, db_is_unnamed_scope(), FALSE, free_safe, funit_inst_s::funit, funit_is_unnamed(), line_display_instance_summary(), statistic_s::line_hit, statistic_s::line_total, funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, scope_gen_printable(), statistic_s::show, funit_inst_s::stat, and funit_inst_s::suppl.
Referenced by line_report().
00275 { PROFILE(LINE_INSTANCE_SUMMARY); 00276 00277 funit_inst* curr; /* Pointer to current child functional unit instance of this node */ 00278 char tmpname[4096]; /* Temporary holder of instance name */ 00279 char* pname; /* Printable version of instance name */ 00280 bool miss_found = FALSE; /* Set to TRUE if a line was found to be missed */ 00281 00282 assert( root != NULL ); 00283 assert( root->stat != NULL ); 00284 00285 /* Get printable version of the instance name */ 00286 pname = scope_gen_printable( root->name ); 00287 00288 /* Calculate instance name */ 00289 if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) { 00290 strcpy( tmpname, parent_inst ); 00291 } else if( strcmp( parent_inst, "*" ) == 0 ) { 00292 strcpy( tmpname, pname ); 00293 } else { 00294 unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent_inst, pname ); 00295 assert( rv < 4096 ); 00296 } 00297 00298 free_safe( pname, (strlen( pname ) + 1) ); 00299 00300 if( (root->funit != NULL) && root->stat->show && !funit_is_unnamed( root->funit ) && 00301 ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit )) ) { 00302 00303 miss_found = line_display_instance_summary( ofile, tmpname, root->stat->line_hit, root->stat->line_total ); 00304 00305 /* Update accumulated information */ 00306 *hits += root->stat->line_hit; 00307 *total += root->stat->line_total; 00308 00309 } 00310 00311 if( (info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit ) ) { 00312 00313 curr = root->child_head; 00314 while( curr != NULL ) { 00315 miss_found |= line_instance_summary( ofile, curr, tmpname, hits, total ); 00316 curr = curr->next; 00317 } 00318 00319 } 00320 00321 PROFILE_END; 00322 00323 return( miss_found ); 00324 00325 }
static void line_instance_verbose | ( | FILE * | ofile, | |
funit_inst * | root, | |||
char * | parent_inst | |||
) | [static] |
Displays the verbose line coverage results to the specified output stream on an instance basis. The verbose line coverage includes the line numbers (and associated verilog code) and file/functional unit name of the lines that were not hit during simulation.
ofile | Pointer to file to output results to | |
root | Pointer to root node of instance tree to search through | |
parent_inst | Hierarchical path of parent instance |
References funit_inst_s::child_head, db_is_unnamed_scope(), func_unit_s::filename, free_safe, funit_inst_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, line_display_verbose(), statistic_s::line_excluded, statistic_s::line_hit, statistic_s::line_total, funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, scope_gen_printable(), funit_inst_s::stat, funit_inst_s::suppl, and func_unit_s::type.
Referenced by line_report().
00492 { PROFILE(LINE_INSTANCE_VERBOSE); 00493 00494 funit_inst* curr_inst; /* Pointer to current instance being evaluated */ 00495 char tmpname[4096]; /* Temporary name holder for instance */ 00496 char* pname; /* Printable version of functional unit name */ 00497 00498 assert( root != NULL ); 00499 00500 /* Get printable version of instance name */ 00501 pname = scope_gen_printable( root->name ); 00502 00503 if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) { 00504 strcpy( tmpname, parent_inst ); 00505 } else if( strcmp( parent_inst, "*" ) == 0 ) { 00506 strcpy( tmpname, pname ); 00507 } else { 00508 unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent_inst, pname ); 00509 assert( rv < 4096 ); 00510 } 00511 00512 free_safe( pname, (strlen( pname ) + 1) ); 00513 00514 if( (root->funit != NULL) && !funit_is_unnamed( root->funit ) && 00515 (((root->stat->line_hit < root->stat->line_total) && !report_covered) || 00516 ((root->stat->line_hit > 0) && report_covered) || 00517 ((root->stat->line_excluded > 0) && report_exclusions)) ) { 00518 00519 /* Get printable version of functional unit name */ 00520 pname = scope_gen_printable( funit_flatten_name( root->funit ) ); 00521 00522 fprintf( ofile, "\n" ); 00523 switch( root->funit->type ) { 00524 case FUNIT_MODULE : fprintf( ofile, " Module: " ); break; 00525 case FUNIT_ANAMED_BLOCK : 00526 case FUNIT_NAMED_BLOCK : fprintf( ofile, " Named Block: " ); break; 00527 case FUNIT_AFUNCTION : 00528 case FUNIT_FUNCTION : fprintf( ofile, " Function: " ); break; 00529 case FUNIT_ATASK : 00530 case FUNIT_TASK : fprintf( ofile, " Task: " ); break; 00531 default : fprintf( ofile, " UNKNOWN: " ); break; 00532 } 00533 fprintf( ofile, "%s, File: %s, Instance: %s\n", pname, obf_file( root->funit->filename ), tmpname ); 00534 fprintf( ofile, " -------------------------------------------------------------------------------------------------------------\n" ); 00535 00536 free_safe( pname, (strlen( pname ) + 1) ); 00537 00538 if( ((root->stat->line_hit < root->stat->line_total) && !report_covered) || 00539 ((root->stat->line_hit > 0) && report_covered && (!report_exclusions || (root->stat->line_hit > root->stat->line_excluded))) ) { 00540 line_display_verbose( ofile, root->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) ); 00541 } 00542 if( (root->stat->line_excluded > 0) && report_exclusions ) { 00543 line_display_verbose( ofile, root->funit, RPT_TYPE_EXCL ); 00544 } 00545 00546 } 00547 00548 curr_inst = root->child_head; 00549 while( curr_inst != NULL ) { 00550 line_instance_verbose( ofile, curr_inst, tmpname ); 00551 curr_inst = curr_inst->next; 00552 } 00553 00554 PROFILE_END; 00555 00556 }
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 }
unsigned int curr_db |
Index of current database in db_list array that is being handled.
Outputs the exclusion ID for an output coverage point. The exclusion ID can be used by the exclude command for excluding/including coverage points.
Suppresses functional units that do not contain any coverage information from being output to the report file.
Referenced by report_gather_funit_stats(), report_gather_instance_stats(), and report_parse_args().
Informational line for the CDD file.
unsigned int report_comb_depth |
If set to a non-zero value, causes Covered to only generate combinational logic report information for depths up to the number specified.
If set to a boolean value of TRUE, displays covered logic for a particular CDD file. By default, Covered will display uncovered logic. Must be used in conjunction with the -d v|d (verbose output) option.
If set to a boolean value of TRUE, displays excluded coverage points for a particular CDD file. By default, Covered will not display excluded coverage points. This can be useful when used in conjunction with the -x option for including excluded coverage points. Must be used in conjunction with the -d v|d (verbose output) option.
If set to a boolean value of TRUE, provides a coverage information for individual functional unit instances. If set to a value of FALSE, reports coverage information on a functional unit basis, merging results from all instances of same functional unit.