line.c File Reference

#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

Detailed Description

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 }

static bool line_display_funit_summary ( FILE *  ofile,
const char *  name,
const char *  fname,
int  hits,
int  total 
) [static]
Returns:
Returns TRUE if at least one line was found to be missed; otherwise, returns FALSE.

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.

Parameters:
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]
Returns:
Returns TRUE if any missed lines were found.

Outputs the instance summary information to the given output file.

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

static void line_display_verbose ( FILE *  ofile,
func_unit funit,
rpt_type  rtype 
) [static]

Displays the lines missed during simulation to standard output from the specified expression list.

Parameters:
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]
Returns:
Returns TRUE if there where lines that were found to be missed; otherwise, returns FALSE.

Iterates through the functional unit list, displaying the line coverage results (summary format) for each functional unit.

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

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

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 }

static bool line_instance_summary ( FILE *  ofile,
funit_inst root,
char *  parent_inst,
int *  hits,
int *  total 
) [static]
Returns:
Returns TRUE if lines were found to be missed; otherwise, returns FALSE.

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.

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

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

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 }


Variable Documentation

unsigned int curr_db

Index of current database in db_list array that is being handled.

Array of database pointers storing all currently loaded databases.

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.

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