Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

/Users/trevorw/projects/release/covered-0.7.4/src/comb.c File Reference


Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
3/31/2002
The functions in this file are used by the report command to calculate and display all report output for combination logic coverage. Combinational logic coverage is calculated solely from the list of expression trees in the scored design. For each module or instance, the expression list is passed to the calculation routine which iterates through each expression tree, tallying the total number of expression values and the total number of expression values reached.
Every expression contains two possible expression values during simulation: 0 and 1. If an expression evaluated to some unknown value, this is not recorded by Covered. If an expression has evaluated to 0, the WAS_FALSE bit of the expression's supplemental field will be set. If the expression has evaluated to 1 or a value greater than 1, the WAS_TRUE bit of the expression's supplemental field will be set. If both the WAS_FALSE and the WAS_TRUE bits are set after scoring, the expression is considered to be fully covered.
If the expression is an event type, only the WAS_TRUE bit is examined. It it was set during simulation, the event is completely covered; otherwise, the event was not covered during simulation.
For combinational logic, four other expression supplemental bits are used to determine which logical combinations of its two children have occurred during simulation. These four bits are EVAL_A, EVAL_B, EVAL_C, and EVAL_D. If the left and right expressions simultaneously evaluated to 0 during simulation, the EVAL_00 bit is set. If the left and right expressions simultaneously evaluated to 0 and 1, respectively, the EVAL_01 bit is set. If the left and right expressions simultaneously evaluated to 1 and 0, respectively, the EVAL_10 bit is set. If the left and right expression simultaneously evaluated to 1 during simulation, the EVAL_11 bit is set. For an AND-type operation, full coverage is achieved if (EVAL_00 || EVAL_01) && (EVAL_00 || EVAL10) && EVAL_11. For an OR-type operation, full coverage is achieved if (EVAL_10 || EVAL_11) && (EVAL_01 || EVAL11) && EVAL_00. For any other combinational expression (where both the left and right expression trees are non-NULL), full coverage is achieved if all four EVAL_xx bits are set.

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "codegen.h"
#include "comb.h"
#include "db.h"
#include "defines.h"
#include "exclude.h"
#include "expr.h"
#include "func_iter.h"
#include "func_unit.h"
#include "iter.h"
#include "link.h"
#include "obfuscate.h"
#include "ovl.h"
#include "report.h"
#include "util.h"
#include "vector.h"

Functions

int combination_calc_depth (expression *exp, unsigned int curr_depth, bool left)
bool combination_does_multi_exp_need_ul (expression *exp)
void combination_multi_expr_calc (expression *exp, int *ulid, bool ul, bool excluded, unsigned int *hit, unsigned int *excludes, unsigned int *total)
bool combination_is_expr_multi_node (expression *exp)
void combination_get_tree_stats (expression *exp, int *ulid, unsigned int curr_depth, bool excluded, unsigned int *hit, unsigned int *excludes, unsigned int *total)
 Calculates combination logic statistics for a single expression tree.

void combination_reset_counted_exprs (func_unit *funit)
void combination_reset_counted_expr_tree (expression *exp)
 Resets combination counted bits in expression tree.

void combination_get_stats (func_unit *funit, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Calculates combination logic statistics for summary output.

void combination_get_funit_summary (func_unit *funit, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Gets combinational logic summary statistics for specified functional unit.

void combination_get_inst_summary (funit_inst *inst, unsigned int *hit, unsigned int *excluded, unsigned int *total)
 Gets combinational logic summary statistics for specified functional unit instance.

bool combination_display_instance_summary (FILE *ofile, char *name, int hits, int total)
bool combination_instance_summary (FILE *ofile, funit_inst *root, char *parent, int *hits, int *total)
bool combination_display_funit_summary (FILE *ofile, const char *name, const char *fname, int hits, int total)
bool combination_funit_summary (FILE *ofile, funit_link *head, int *hits, int *total)
void combination_draw_line (char *line, int size, int exp_id)
void combination_draw_centered_line (char *line, int size, int exp_id, bool left_bar, bool right_bar)
void combination_parenthesize (bool parenthesis, const char *pre_code_format, char **new_code_format, unsigned int *code_format_size)
void combination_underline_tree (expression *exp, unsigned int curr_depth, char ***lines, unsigned int *depth, unsigned int *size, exp_op_type parent_op, bool center, func_unit *funit)
char * combination_prep_line (char *line, int start, int len)
void combination_underline (FILE *ofile, char **code, unsigned int code_depth, expression *exp, func_unit *funit)
void combination_unary (char ***info, int *info_size, expression *exp, bool show_excluded)
void combination_event (char ***info, int *info_size, expression *exp, bool show_excluded)
void combination_two_vars (char ***info, int *info_size, expression *exp, bool show_excluded)
void combination_multi_var_exprs (char **line1, char **line2, char **line3, expression *exp)
int combination_multi_expr_output_length (char *line1)
void combination_multi_expr_output (char **info, char *line1, char *line2, char *line3)
void combination_multi_vars (char ***info, int *info_size, expression *exp, bool show_excluded)
void combination_get_missed_expr (char ***info, int *info_size, expression *exp, unsigned int curr_depth, bool show_excluded)
void combination_list_missed (FILE *ofile, expression *exp, unsigned int curr_depth, func_unit *funit, bool show_exclusions)
void combination_output_expr (expression *expr, unsigned int curr_depth, int *any_missed, int *any_measurable, int *any_excluded, int *all_excluded)
void combination_display_verbose (FILE *ofile, func_unit *funit, rpt_type rtype)
void combination_instance_verbose (FILE *ofile, funit_inst *root, char *parent)
void combination_funit_verbose (FILE *ofile, funit_link *head)
void combination_collect (func_unit *funit, int cov, expression ***exprs, unsigned int *exp_cnt, int **excludes)
 Collects all toggle expressions that match the specified coverage indication.

void combination_get_exclude_list (expression *exp, func_unit *funit, int **excludes, char ***reasons, unsigned int *exclude_size)
void combination_get_expression (int expr_id, char ***code, int **uline_groups, unsigned int *code_size, char ***ulines, unsigned int *uline_size, int **excludes, char ***reasons, unsigned int *exclude_size)
 Gets output for specified expression including underlines and code.

void combination_get_coverage (int exp_id, int uline_id, char ***info, int *info_size)
 Gets output for specified expression including coverage information.

void combination_report (FILE *ofile, bool verbose)
 Generates report output for combinational logic coverage.


Variables

db ** db_list
unsigned int curr_db
bool report_covered
unsigned int report_comb_depth
bool report_instance
bool report_bitwise
int line_width
char user_msg [USER_MSG_LENGTH]
const exp_info exp_op_info [EXP_OP_NUM]
isuppl info_suppl
bool report_exclusions
bool flag_output_exclusion_ids
bool allow_multi_expr = TRUE


Function Documentation

int combination_calc_depth expression exp,
unsigned int  curr_depth,
bool  left
[static]
 

Returns:
Returns new depth value for specified child expression.
Based on the current point in the expression tree, calculates the left or right child's curr_depth value.
Parameters:
exp  Pointer to current expression
curr_depth  Current depth in expression tree
left  TRUE if evaluating for left child

00112   { PROFILE(COMBINATION_CALC_DEPTH);
00113 
00114   int our_depth;  /* Return value for this function */
00115 
00116   if( ((report_comb_depth == REPORT_DETAILED) && ((curr_depth + 1) <= report_comb_depth)) ||
00117        (report_comb_depth == REPORT_VERBOSE) ) {
00118 
00119     if( left ) {
00120 
00121       if( (exp->left != NULL) && (exp->op == exp->left->op) ) {
00122         our_depth = curr_depth;
00123       } else {
00124         our_depth = curr_depth + 1;
00125       }
00126 
00127     } else {
00128 
00129       if( (exp->right != NULL) && (exp->op == exp->right->op) ) {
00130         our_depth = curr_depth;
00131       } else {
00132         our_depth = curr_depth + 1;
00133       }
00134 
00135     }
00136 
00137   } else {
00138 
00139     our_depth = curr_depth + 1;
00140 
00141   }
00142 
00143   PROFILE_END;
00144 
00145   return( our_depth );
00146 
00147 }

void combination_collect func_unit funit,
int  cov,
expression ***  exprs,
unsigned int *  exp_cnt,
int **  excludes
 

Collects all toggle expressions that match the specified coverage indication.

Gathers the covered or uncovered combinational logic information, storing their expressions in the exprs expression arrays. Used by the GUI for verbose combinational logic output.

Parameters:
funit  Pointer to functional unit
cov  Specifies the coverage type to find
exprs  Pointer to an array of expression pointers that contain all fully covered/uncovered expressions
exp_cnt  Pointer to a value that will be set to indicate the number of expressions in covs array
excludes  Pointer to an array of integers indicating exclusion property of each uncovered expression

02786   { PROFILE(COMBINATION_COLLECT);
02787 
02788   func_iter  fi;              /* Functional unit iterator */
02789   statement* stmt;            /* Pointer to current statement */
02790  
02791   /* Reset combination counted bits */
02792   combination_reset_counted_exprs( funit );
02793 
02794   /* Create an array that will hold the number of uncovered combinations */
02795   *exp_cnt  = 0;
02796   *exprs    = NULL;
02797   *excludes = NULL;
02798 
02799   func_iter_init( &fi, funit, TRUE, FALSE );
02800 
02801   stmt = func_iter_get_next_statement( &fi );
02802   while( stmt != NULL ) {
02803 
02804     int any_missed     = 0;
02805     int any_measurable = 0;
02806     int any_excluded   = 0;
02807     int all_excluded   = 0;
02808 
02809     combination_output_expr( stmt->exp, 0, &any_missed, &any_measurable, &any_excluded, &all_excluded );
02810 
02811     /* Check for uncovered statements */
02812     if( ((cov == 0) && (any_missed == 1)) ||
02813         ((cov == 1) && (any_missed == 0) && (any_measurable == 1)) ) {
02814       if( stmt->exp->line != 0 ) {
02815         *exprs    = (expression**)realloc_safe( *exprs,    (sizeof( expression* ) * (*exp_cnt)), (sizeof( expression* ) * (*exp_cnt + 1)) );
02816         *excludes =         (int*)realloc_safe( *excludes, (sizeof( int* )        * (*exp_cnt)), (sizeof( int* )        * (*exp_cnt + 1)) );
02817 
02818         (*exprs)[(*exp_cnt)]    = stmt->exp;
02819         (*excludes)[(*exp_cnt)] = all_excluded ? 1 : 0;
02820         (*exp_cnt)++;
02821       }
02822       stmt->exp->suppl.part.comb_cntd = 0;
02823     }
02824 
02825     stmt = func_iter_get_next_statement( &fi );
02826 
02827   }
02828 
02829   func_iter_dealloc( &fi );
02830 
02831   PROFILE_END;
02832 
02833 }

bool combination_display_funit_summary FILE *  ofile,
const char *  name,
const char *  fname,
int  hits,
int  total
[static]
 

Returns:
Returns TRUE if at least one logic combination was found to not be hit; otherwise, returns FALSE.
Outputs the summary combinational logic information for the specified functional unit to the given output stream.
Parameters:
ofile  Pointer to file to output functional unit summary information to
name  Name of functional unit being reported
fname  Filename that contains the functional unit being reported
hits  Number of logic combinations that were hit during simulation
total  Number of total logic combinations that exist in the given functional unit

00700   { PROFILE(COMBINATION_DISPLAY_FUNIT_SUMMARY);
00701 
00702   float percent;  /* Percentage of lines hit */
00703   int   miss;     /* Number of lines missed */
00704 
00705   calc_miss_percent( hits, total, &miss, &percent );
00706 
00707   fprintf( ofile, "  %-30.30s    %-30.30s   %4d/%4d/%4d      %3.0f%%\n",
00708            name, fname, hits, miss, total, percent );
00709 
00710   PROFILE_END;
00711 
00712   return( miss > 0 );
00713 
00714 }

bool combination_display_instance_summary FILE *  ofile,
char *  name,
int  hits,
int  total
[static]
 

Outputs the instance combinational logic summary information to the given output file.

Parameters:
ofile  Pointer to file to output instance summary to
name  Name of instance to display
hits  Number of combinations hit in instance
total  Total number of logic combinations in instance

00604   { PROFILE(COMBINATION_DISPLAY_INSTANCE_SUMMARY);
00605 
00606   float percent;  /* Percentage of lines hit */
00607   int   miss;     /* Number of lines missed */
00608 
00609   calc_miss_percent( hits, total, &miss, &percent );
00610 
00611   fprintf( ofile, "  %-63.63s    %4d/%4d/%4d      %3.0f%%\n",
00612            name, hits, miss, total, percent );
00613 
00614   PROFILE_END;
00615 
00616   return( miss > 0 );
00617 
00618 }

void combination_display_verbose FILE *  ofile,
func_unit funit,
rpt_type  rtype
[static]
 

Exceptions:
anonymous combination_underline
Displays the expressions (and groups of expressions) that were considered to be measurable (evaluates to a value of TRUE (1) or FALSE (0) but were not hit during simulation. The entire Verilog expression is displayed to the specified output stream with each of its measured expressions being underlined and numbered. The missed combinations are then output below the Verilog code, showing those logical combinations that were not hit during simulation.
Parameters:
ofile  Pointer to file to output results to
funit  Pointer to functional unit to display verbose combinational logic output for
rtype  Specifies the type of report to display

02581   { PROFILE(COMBINATION_DISPLAY_VERBOSE);
02582 
02583   func_iter    fi;          /* Functional unit iterator */
02584   statement*   stmt;        /* Pointer to current statement */
02585   char**       code;        /* Code string from code generator */
02586   unsigned int code_depth;  /* Depth of code array */
02587 
02588   switch( rtype ) {
02589     case RPT_TYPE_HIT  :  fprintf( ofile, "    Hit Combinations\n\n" );                         break;
02590     case RPT_TYPE_MISS :  fprintf( ofile, "    Missed Combinations  (* = missed value)\n\n" );  break;
02591     case RPT_TYPE_EXCL :  fprintf( ofile, "    Excluded Combinations\n\n" );                    break;
02592   }
02593 
02594   /* Initialize functional unit iterator */
02595   func_iter_init( &fi, funit, TRUE, FALSE );
02596 
02597   /* Display missed combinations */
02598   stmt = func_iter_get_next_statement( &fi );
02599   while( stmt != NULL ) {
02600 
02601     int any_missed     = 0;
02602     int any_measurable = 0;
02603     int any_excluded   = 0;
02604     int all_excluded   = 0;
02605 
02606     combination_output_expr( stmt->exp, 0, &any_missed, &any_measurable, &any_excluded, &all_excluded );
02607 
02608     if( ((rtype == RPT_TYPE_MISS) && (any_missed == 1) && (all_excluded == 0) && (any_measurable == 1)) ||
02609         ((rtype == RPT_TYPE_HIT)  && (any_missed == 0) && (any_measurable == 1)) ||
02610         ((rtype == RPT_TYPE_EXCL) && (any_excluded == 1)) ) {
02611 
02612       stmt->exp->suppl.part.comb_cntd = 0;
02613 
02614       fprintf( ofile, "      =========================================================================================================\n" );
02615       fprintf( ofile, "       Line #     Expression\n" );
02616       fprintf( ofile, "      =========================================================================================================\n" );
02617 
02618       /* Generate line of code that missed combinational coverage */
02619       codegen_gen_expr( stmt->exp, stmt->exp->op, &code, &code_depth, funit );
02620 
02621       /* Output underlining feature for missed expressions */
02622       combination_underline( ofile, code, code_depth, stmt->exp, funit );
02623       fprintf( ofile, "\n" );
02624 
02625       /* Output logical combinations that missed complete coverage */
02626       combination_list_missed( ofile, stmt->exp, 0, funit, (rtype == RPT_TYPE_EXCL) );
02627 
02628     }
02629     
02630     stmt = func_iter_get_next_statement( &fi );
02631 
02632   }
02633 
02634   /* Deallocate functional unit iterator */
02635   func_iter_dealloc( &fi );
02636 
02637   PROFILE_END;
02638 
02639 }

bool combination_does_multi_exp_need_ul expression exp  )  [static]
 

Returns:
Returns TRUE if the given expression multi-expression tree needs to be underlined
Parameters:
exp  Pointer to expression to check for multi-expression underlines

00154   { PROFILE(COMBINATION_DOES_MULTI_EXP_NEED_UL);
00155 
00156   bool ul = FALSE;  /* Return value for this function */
00157   bool and_op;      /* Specifies if current expression is an AND or LAND operation */
00158 
00159   if( exp != NULL ) {
00160 
00161     /* Figure out if this is an AND/LAND operation */
00162     and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND);
00163 
00164     /* Decide if our expression requires that this sequence gets underlined */
00165     if( and_op ) {
00166       ul = (exp->suppl.part.eval_11 == 0) || (ESUPPL_WAS_FALSE( exp->left->suppl ) == 0) || (ESUPPL_WAS_FALSE( exp->right->suppl ) == 0);
00167     } else {
00168       ul = (exp->suppl.part.eval_00 == 0) || (ESUPPL_WAS_TRUE( exp->left->suppl )  == 0) || (ESUPPL_WAS_TRUE( exp->right->suppl )  == 0);
00169     }
00170 
00171     /* If we did not require underlining, check our left child */
00172     if( !ul && ((exp->left == NULL) || (exp->op == exp->left->op)) ) {
00173       ul = combination_does_multi_exp_need_ul( exp->left );
00174     }
00175 
00176     /* If we still have not found a reason to underline, check our right child */
00177     if( !ul && ((exp->right == NULL) || (exp->op == exp->right->op)) ) {
00178       ul = combination_does_multi_exp_need_ul( exp->right );
00179     }
00180 
00181   }
00182 
00183   PROFILE_END;
00184 
00185   return( ul );
00186 
00187 }

void combination_draw_centered_line char *  line,
int  size,
int  exp_id,
bool  left_bar,
bool  right_bar
[static]
 

Draws an underline containing the specified expression ID to the specified line. The expression ID will be placed in the center of the generated underline.

Parameters:
line  Pointer to line to create line onto
size  Number of characters long line is
exp_id  ID to place in underline
left_bar  If set to TRUE, draws a vertical bar at the beginning of the underline
right_bar  If set to TRUE, draws a vertical bar at the end of the underline

00807   { PROFILE(COMBINATION_DRAW_CENTERED_LINE);
00808 
00809   char         str_exp_id[12];   /* String containing value of exp_id */
00810   int          exp_id_size;      /* Number of characters exp_id is in length */
00811   int          i;                /* Loop iterator */
00812   unsigned int rv;               /* Return value from snprintf call */
00813 
00814   /* Calculate size of expression ID */
00815   rv = snprintf( str_exp_id, 12, "%d", exp_id );
00816   assert( rv < 12 );
00817   exp_id_size = strlen( str_exp_id );
00818 
00819   if( left_bar ) {
00820     line[0] = '|';
00821   } else {
00822     line[0] = '-';
00823   }
00824 
00825   for( i=1; i<((size - exp_id_size) / 2); i++ ) {
00826     line[i] = '-';
00827   }
00828 
00829   line[i] = '\0';
00830   strcat( line, str_exp_id );
00831 
00832   for( i=(i + exp_id_size); i<(size - 1); i++ ) {
00833     line[i] = '-';
00834   }
00835 
00836   if( right_bar ) {
00837     line[i] = '|';
00838   } else {
00839     line[i] = '-';
00840   }
00841   line[i+1] = '\0';
00842 
00843   PROFILE_END;
00844 
00845 }

void combination_draw_line char *  line,
int  size,
int  exp_id
[static]
 

Draws an underline containing the specified expression ID to the specified line. The expression ID will be placed immediately following the beginning vertical bar.

Parameters:
line  Pointer to line to create line onto
size  Number of characters long line is
exp_id  ID to place in underline

00770   { PROFILE(COMBINATION_DRAW_LINE);
00771 
00772   char         str_exp_id[12];  /* String containing value of exp_id */
00773   int          exp_id_size;     /* Number of characters exp_id is in length */
00774   int          i;               /* Loop iterator */
00775   unsigned int rv;              /* Return value from calls to snprintf */
00776 
00777   /* Calculate size of expression ID */
00778   rv = snprintf( str_exp_id, 12, "%d", exp_id );
00779   assert( rv < 12 );
00780   exp_id_size = strlen( str_exp_id );
00781 
00782   line[0] = '|';
00783   line[1] = '\0';
00784   strcat( line, str_exp_id );
00785 
00786   for( i=(exp_id_size + 1); i<(size - 1); i++ ) {
00787     line[i] = '-';
00788   }
00789 
00790   line[i]   = '|';
00791   line[i+1] = '\0';
00792 
00793   PROFILE_END;
00794 
00795 }

void combination_event char ***  info,
int *  info_size,
expression exp,
bool  show_excluded
[static]
 

Displays the missed unary combination(s) that keep the combination coverage for the specified expression from achieving 100% coverage.

Parameters:
info  Pointer to array of strings that will contain the coverage information for this expression
info_size  Pointer to integer containing number of elements in info array
exp  Pointer to expression to evaluate
show_excluded  Set to TRUE to output the expression if it is excluded

01678   { PROFILE(COMBINATION_EVENT);
01679 
01680   char         tmp[20];
01681   unsigned int length;
01682   char*        op = exp_op_info[exp->op].op_str;  /* Operation string */
01683 
01684   assert( exp != NULL );
01685 
01686   if( !ESUPPL_WAS_TRUE( exp->suppl ) || (exp->suppl.part.excluded && show_excluded) ) {
01687 
01688     char         spaces[30];
01689     unsigned int rv;
01690     unsigned int eid_size;
01691 
01692     if( flag_output_exclusion_ids ) {
01693       eid_size = db_get_exclusion_id_size();
01694     }
01695 
01696     spaces[0] = '\0';
01697 
01698     assert( exp->ulid != -1 );
01699 
01700     /* Allocate memory for info array */
01701     *info_size = 3;
01702     *info      = (char**)malloc_safe( sizeof( char* ) * (*info_size) );
01703 
01704     /* Allocate lines and assign values */
01705     length = 28;  rv = snprintf( tmp, 20, "%d", exp->ulid );  assert( rv < 20 );  length += strlen( tmp );
01706     if( flag_output_exclusion_ids ) {
01707       length += (eid_size - 1) + 4;
01708       gen_char_string( spaces, ' ', ((eid_size - 1) + 4) );
01709     }
01710     (*info)[0] = (char*)malloc_safe( length );
01711     if( flag_output_exclusion_ids ) {
01712       rv = snprintf( (*info)[0], length, "        (%s)  Expression %d   (0/1)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid );
01713     } else {
01714       rv = snprintf( (*info)[0], length, "        Expression %d   (0/1)", exp->ulid );
01715     }
01716     assert( rv < length );
01717 
01718     length = 25 + strlen( op ) + strlen( spaces );
01719     (*info)[1] = (char*)malloc_safe( length );  rv = snprintf( (*info)[1], length, "%s        ^^^^^^^^^^^^^ - %s", spaces, op );  assert( rv < length );
01720     length = 31 + strlen( spaces );
01721     (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s         * Event did not occur", spaces );  assert( rv < length );
01722 
01723   }
01724 
01725   PROFILE_END;
01726 
01727 }

bool combination_funit_summary FILE *  ofile,
funit_link head,
int *  hits,
int *  total
[static]
 

Returns:
Returns TRUE if combinations were found to be missed; otherwise, returns FALSE.
Outputs summarized results of the combinational logic coverage per functional unit to the specified output stream. Summarized results are printed as percentages based on the number of combinations hit during simulation divided by the total number of expression combinations possible in the design. An expression is said to be measurable for combinational coverage if it evaluates to a value of 0 or 1.
Parameters:
ofile  Pointer to file to output results to
head  Pointer to link in current functional unit list to evaluate
hits  Pointer to number of combinations hit in all functional units
total  Pointer to total number of combinations found in all functional units

00732   { PROFILE(COMBINATION_FUNIT_SUMMARY);
00733 
00734   bool miss_found = FALSE;  /* Set to TRUE if missing combinations were found */
00735 
00736   while( head != NULL ) {
00737 
00738     /* If this is an assertion module, don't output any further */
00739     if( head->funit->stat->show && !funit_is_unnamed( head->funit ) &&
00740         ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( head->funit )) ) {
00741 
00742       miss_found |= combination_display_funit_summary( ofile, obf_funit( funit_flatten_name( head->funit ) ), get_basename( obf_file( head->funit->filename ) ),
00743                                                        head->funit->stat->comb_hit, head->funit->stat->comb_total );
00744 
00745       /* Update accumulated information */
00746       *hits  += head->funit->stat->comb_hit;
00747       *total += head->funit->stat->comb_total;
00748 
00749     }
00750 
00751     head = head->next;
00752 
00753   }
00754 
00755   PROFILE_END;
00756 
00757   return( miss_found );
00758 
00759 }

void combination_funit_verbose FILE *  ofile,
funit_link head
[static]
 

Exceptions:
anonymous combination_display_verbose
Outputs the verbose coverage report for the specified functional unit to the specified output stream.
Parameters:
ofile  Pointer to file to output results to
head  Pointer to current functional unit to evaluate

02727   { PROFILE(COMBINATION_FUNIT_VERBOSE);
02728 
02729   char* pname;  /* Printable version of functional unit name */
02730 
02731   while( head != NULL ) {
02732 
02733     if( !funit_is_unnamed( head->funit ) &&
02734         (((head->funit->stat->comb_hit < head->funit->stat->comb_total) && !report_covered) ||
02735          ((head->funit->stat->comb_hit > 0) && report_covered) ||
02736          ((head->funit->stat->comb_excluded > 0) && report_exclusions)) ) {
02737 
02738       /* Get printable version of functional unit name */
02739       pname = scope_gen_printable( funit_flatten_name( head->funit ) );
02740 
02741       fprintf( ofile, "\n" );
02742       switch( head->funit->type ) {
02743         case FUNIT_MODULE       :  fprintf( ofile, "    Module: " );       break;
02744         case FUNIT_ANAMED_BLOCK :
02745         case FUNIT_NAMED_BLOCK  :  fprintf( ofile, "    Named Block: " );  break;
02746         case FUNIT_AFUNCTION    :
02747         case FUNIT_FUNCTION     :  fprintf( ofile, "    Function: " );     break;
02748         case FUNIT_ATASK        :
02749         case FUNIT_TASK         :  fprintf( ofile, "    Task: " );         break;
02750         default                 :  fprintf( ofile, "    UNKNOWN: " );      break;
02751       }
02752       fprintf( ofile, "%s, File: %s\n", pname, obf_file( head->funit->filename ) );
02753       fprintf( ofile, "    -------------------------------------------------------------------------------------------------------------\n" );
02754 
02755       free_safe( pname, (strlen( pname ) + 1) );
02756 
02757       if( ((head->funit->stat->comb_hit < head->funit->stat->comb_total) && !report_covered) ||
02758           ((head->funit->stat->comb_hit > 0) && report_covered && (!report_exclusions || (head->funit->stat->comb_hit > head->funit->stat->comb_excluded))) ) {
02759         combination_display_verbose( ofile, head->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) );
02760       }
02761       if( (head->funit->stat->comb_excluded > 0) && report_exclusions ) {
02762         combination_reset_counted_exprs( head->funit );
02763         combination_display_verbose( ofile, head->funit, RPT_TYPE_EXCL );
02764       }
02765 
02766     }
02767 
02768     head = head->next;
02769 
02770   }
02771 
02772   PROFILE_END;
02773 
02774 }

void combination_get_coverage int  exp_id,
int  uline_id,
char ***  info,
int *  info_size
 

Gets output for specified expression including coverage information.

Returns:
Returns TRUE if we were successful in obtaining coverage detail for the specified information; otherwise, returns FALSE to indicate an error.
Calculates the coverage detail for the specified subexpression and stores this in string format in the info and info_size arguments. The coverage detail created matches the coverage detail output format that is used in the ASCII reports.
Parameters:
exp_id  Expression ID of statement containing subexpression to get coverage detail for
uline_id  Underline ID of subexpression to get coverage detail for
info  Pointer to string array that will be populated with the coverage detail
info_size  Number of entries in info array

03010   { PROFILE(COMBINATION_GET_COVERAGE);
03011 
03012   func_unit*  funit;  /* Pointer to found functional unit */
03013   exp_link*   expl;   /* Pointer to current expression link */
03014   expression* exp;    /* Pointer to found expression */
03015 
03016   /* Find the functional unit that contains this expression */
03017   funit = funit_find_by_id( exp_id );
03018   assert( funit != NULL );
03019 
03020   /* Find statement containing this expression */
03021   expl = exp_link_find( exp_id, funit->exp_head );
03022   assert( expl != NULL );
03023 
03024   /* Now find the subexpression that matches the given underline ID */
03025   exp = expression_find_uline_id( expl->exp, uline_id );
03026   assert( exp != NULL );
03027 
03028   combination_get_missed_expr( info, info_size, exp, 0, TRUE );
03029 
03030   PROFILE_END;
03031 
03032 }

void combination_get_exclude_list expression exp,
func_unit funit,
int **  excludes,
char ***  reasons,
unsigned int *  exclude_size
[static]
 

Recursively iterates through the specified expression tree, storing the exclude values for each underlined expression within the tree. The values are stored in the excludes parameter and its size is stored in the exclude_size parameter.

Parameters:
exp  Pointer to current expression
funit  Pointer to functional unit containing the exclude reasons for this expression tree
excludes  Array of exclude values for each underlined expression in this tree
reasons  Array of exclude reasons for each underlined expression in this tree
exclude_size  Number of elements in the excludes array

02846   { PROFILE(COMBINATION_GET_EXCLUDE_LIST);
02847 
02848   if( exp != NULL ) {
02849 
02850     /* Store the exclude value for this expression */
02851     if( exp->ulid != -1 ) {
02852 
02853       exclude_reason* er;
02854      
02855       if( (exp->ulid > 0) && ((unsigned int)exp->ulid > *exclude_size) ) {
02856         int i;
02857         *excludes     = (int*)realloc_safe( *excludes, (sizeof( int ) * exp->ulid), (sizeof( int ) * (exp->ulid + 1)) );
02858         *reasons      = (char**)realloc_safe( *reasons, (sizeof( int ) * exp->ulid), (sizeof( int ) * (exp->ulid + 1)) );
02859         for( i=*exclude_size; i<exp->ulid; i++ ) {
02860           (*excludes)[i] = 0;
02861           (*reasons)[i]  = NULL;
02862         }
02863         *exclude_size = exp->ulid + 1;
02864       }
02865 
02866       (*excludes)[exp->ulid] = ESUPPL_EXCLUDED( exp->suppl );
02867 
02868       /* If the expression is currently excluded, check to see if there's a reason associated with it */
02869       if( (ESUPPL_EXCLUDED( exp->suppl ) == 1) && ((er = exclude_find_exclude_reason( 'E', exp->id, funit )) != NULL) ) {
02870         (*reasons)[exp->ulid] = strdup_safe( er->reason );
02871       } else {
02872         (*reasons)[exp->ulid] = NULL;
02873       }
02874 
02875     }
02876 
02877     /* Get exclude values for children */
02878     combination_get_exclude_list( exp->left,  funit, excludes, reasons, exclude_size );
02879     combination_get_exclude_list( exp->right, funit, excludes, reasons, exclude_size );
02880 
02881   }
02882 
02883   PROFILE_END;
02884 
02885 }

void combination_get_expression int  expr_id,
char ***  code,
int **  uline_groups,
unsigned int *  code_size,
char ***  ulines,
unsigned int *  uline_size,
int **  excludes,
char ***  reasons,
unsigned int *  exclude_size
 

Gets output for specified expression including underlines and code.

Exceptions:
anonymous Throw combination_underline_tree
Gets the combinational logic coverage information for the specified expression ID, storing the output in the code and ulines arrays. Used by the GUI for displaying an expression's coverage information.
Parameters:
expr_id  Expression ID to retrieve information for
code  Pointer to an array of strings containing generated code for this expression
uline_groups  Pointer to an array of integers used for underlined missed subexpressions in this expression
code_size  Pointer to value that will be set to indicate the number of elements in the code array
ulines  Pointer to an array of strings that contain underlines of missed subexpressions
uline_size  Pointer to value that will be set to indicate the number of elements in the ulines array
excludes  Pointer to an array of values that determine if the associated subexpression is currently excluded or not from coverage
reasons  Pointer to an array of strings that specify the reason for exclusion
exclude_size  Pointer to value that will be set to indicate the number of elements in excludes

02904   { PROFILE(COMBINATION_GET_EXPRESSION);
02905 
02906   exp_link*    expl;              /* Pointer to found signal link */
02907   unsigned int tmp;               /* Temporary integer (unused) */
02908   unsigned int i, j;              /* Loop iterators */
02909   char**       tmp_ulines;
02910   unsigned int tmp_uline_size;
02911   int          start     = 0;
02912   unsigned int uline_max = 20;
02913   func_unit*   funit;
02914 
02915   /* Find functional unit that contains this expression */
02916   funit = funit_find_by_id( expr_id );
02917   assert( funit != NULL );
02918 
02919   /* Find the expression itself */
02920   expl = exp_link_find( expr_id, funit->exp_head );
02921   assert( expl != NULL );
02922 
02923   /* Generate line of code that missed combinational coverage */
02924   codegen_gen_expr( expl->exp, expl->exp->op, code, code_size, funit );
02925   *uline_groups = (int*)malloc_safe( sizeof( int ) * (*code_size) );
02926 
02927   /* Generate exclude information */
02928   *excludes     = NULL;
02929   *reasons      = NULL;
02930   *exclude_size = 0;
02931   combination_get_exclude_list( expl->exp, funit_get_curr_module( funit ), excludes, reasons, exclude_size );
02932 
02933   Try {
02934 
02935     /* Output underlining feature for missed expressions */
02936     combination_underline_tree( expl->exp, 0, &tmp_ulines, &tmp_uline_size, &tmp, expl->exp->op, (*code_size == 1), funit );
02937   
02938   } Catch_anonymous {
02939     unsigned int i;
02940     free_safe( *uline_groups, (sizeof( int ) * (*code_size)) );
02941     *uline_groups = NULL;
02942     for( i=0; i<*code_size; i++ ) {
02943       free_safe( (*code)[i], (strlen( (*code)[i] ) + 1) );
02944     }
02945     free_safe( *code, (sizeof( char* ) * *code_size) );
02946     *code      = NULL;
02947     *code_size = 0;
02948     free_safe( *excludes, (sizeof( int* ) * *exclude_size) );
02949     *excludes     = NULL;
02950     *exclude_size = 0;
02951     Throw 0;
02952   }
02953 
02954   *ulines     = (char**)malloc_safe( sizeof( char* ) * uline_max );
02955   *uline_size = 0;
02956 
02957   for( i=0; i<*code_size; i++ ) {
02958 
02959     assert( (*code)[i] != NULL );
02960 
02961     (*uline_groups)[i] = 0;
02962 
02963     if( *code_size == 1 ) {
02964       *ulines            = tmp_ulines;
02965       *uline_size        = tmp_uline_size;
02966       (*uline_groups)[0] = tmp_uline_size;
02967       tmp_uline_size     = 0;
02968     } else {
02969       for( j=0; j<tmp_uline_size; j++ ) {
02970         if( ((*ulines)[*uline_size] = combination_prep_line( tmp_ulines[j], start, strlen( (*code)[i] ) )) != NULL ) {
02971           ((*uline_groups)[i])++;
02972           (*uline_size)++;
02973           if( *uline_size == uline_max ) {
02974             uline_max += 20;
02975             *ulines    = (char**)realloc_safe( *ulines, (sizeof( char* ) * (uline_max - 20)), (sizeof( char* ) * uline_max) );
02976           }
02977         }
02978       }
02979     }
02980 
02981     start += strlen( (*code)[i] );
02982 
02983   }
02984 
02985   for( i=0; i<tmp_uline_size; i++ ) {
02986     free_safe( tmp_ulines[i], (strlen( tmp_ulines[i] ) + 1) );
02987   }
02988 
02989   if( tmp_uline_size > 0 ) {
02990     free_safe( tmp_ulines, (sizeof( char* ) * tmp_uline_size) );
02991   }
02992 
02993   PROFILE_END;
02994 
02995 }

void combination_get_funit_summary func_unit funit,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total
 

Gets combinational logic summary statistics for specified functional unit.

Retrieves the combinational logic summary information for the specified functional unit

Parameters:
funit  Pointer to functional unit
hit  Pointer to location to store the number of hit combinations for the specified functional unit
excluded  Pointer to number of excluded logical combinations
total  Pointer to location to store the total number of combinations for the specified functional unit

00568   { PROFILE(COMBINATION_GET_FUNIT_SUMMARY);
00569 
00570   *hit      = funit->stat->comb_hit;
00571   *excluded = funit->stat->comb_excluded;
00572   *total    = funit->stat->comb_total;
00573 
00574   PROFILE_END;
00575 
00576 }

void combination_get_inst_summary funit_inst inst,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total
 

Gets combinational logic summary statistics for specified functional unit instance.

Retrieves the combinational logic summary information for the specified functional unit instance

Parameters:
inst  Pointer to functional unit instance
hit  Pointer to location to store the number of hit combinations for the specified functional unit instance
excluded  Pointer to number of excluded logical combinations
total  Pointer to location to store the total number of combinations for the specified functional unit instance

00586   { PROFILE(COMBINATION_GET_INST_SUMMARY);
00587   
00588   *hit      = inst->stat->comb_hit;
00589   *excluded = inst->stat->comb_excluded;
00590   *total    = inst->stat->comb_total;
00591             
00592   PROFILE_END;
00593   
00594 }

void combination_get_missed_expr char ***  info,
int *  info_size,
expression exp,
unsigned int  curr_depth,
bool  show_excluded
[static]
 

Calculates the missed coverage detail output for the given expression, placing the output to the info array. This array can then be sent to an ASCII report file or the GUI.

Parameters:
info  Pointer to an array of strings containing expression coverage detail
info_size  Pointer to a value that will be set to indicate the number of valid elements in the info array
exp  Pointer to the expression to get the coverage detail for
curr_depth  Current expression depth (used to figure out when to stop getting coverage information -- if the user has specified a maximum depth)
show_excluded  Set to TRUE if excluded expressions should be output

02412   { PROFILE(COMBINATION_GET_MISSED_EXPR);
02413 
02414   assert( exp != NULL );
02415 
02416   *info_size = 0;
02417 
02418   if( EXPR_COMB_MISSED( exp ) &&
02419       (((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) ||
02420         (report_comb_depth == REPORT_VERBOSE)) ) {
02421  
02422     if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ||
02423         ((exp->op != EXP_OP_AND)  &&
02424          (exp->op != EXP_OP_LAND) &&
02425          (exp->op != EXP_OP_OR)   &&
02426          (exp->op != EXP_OP_LOR)) ) {
02427 
02428       if( (((exp->left != NULL) &&
02429             (exp->op == exp->left->op)) ||
02430            ((exp->right != NULL) &&
02431             (exp->op == exp->right->op))) &&
02432           ((exp->op == EXP_OP_AND)  ||
02433            (exp->op == EXP_OP_OR)   ||
02434            (exp->op == EXP_OP_LAND) ||
02435            (exp->op == EXP_OP_LOR)) ) {
02436 
02437         combination_multi_vars( info, info_size, exp, show_excluded );
02438 
02439       } else {
02440 
02441         /* Create combination table */
02442         if( EXPR_IS_COMB( exp ) ) {
02443           combination_two_vars( info, info_size, exp, show_excluded );
02444         } else if( EXPR_IS_EVENT( exp ) ) {
02445           combination_event( info, info_size, exp, show_excluded );
02446         } else {
02447           combination_unary( info, info_size, exp, show_excluded );
02448         }
02449 
02450       }
02451 
02452     }
02453 
02454   }
02455 
02456   PROFILE_END;
02457 
02458 }

void combination_get_stats func_unit funit,
unsigned int *  hit,
unsigned int *  excluded,
unsigned int *  total
 

Calculates combination logic statistics for summary output.

Iterates through specified expression list and finds all root expressions. For each root expression, the combination_get_tree_stats function is called to generate the coverage numbers for the specified expression tree. Called by report function.

Parameters:
funit  Pointer to functional unit to search
hit  Pointer to number of logical combinations hit during simulation
excluded  Pointer to number of excluded logical combinations
total  Pointer to total number of logical combinations

00533   { PROFILE(COMBINATION_GET_STATS);
00534 
00535   func_iter  fi;    /* Functional unit iterator */
00536   statement* stmt;  /* Pointer to current statement being examined */
00537   int        ulid;  /* Current underline ID for this expression */
00538   
00539   /* If the given functional unit is not an unnamed scope, traverse it now */
00540   if( !funit_is_unnamed( funit ) ) {
00541 
00542     /* Initialize functional unit iterator */
00543     func_iter_init( &fi, funit, TRUE, FALSE );
00544 
00545     /* Traverse statements in the given functional unit */
00546     while( (stmt = func_iter_get_next_statement( &fi )) != NULL ) {
00547       ulid = 1;
00548       combination_get_tree_stats( stmt->exp, &ulid, 0, stmt->suppl.part.excluded, hit, excluded, total );
00549     }
00550 
00551     /* Deallocate functional unit iterator */
00552     func_iter_dealloc( &fi );
00553 
00554   }
00555 
00556   PROFILE_END;
00557 
00558 }

void combination_get_tree_stats expression exp,
int *  ulid,
unsigned int  curr_depth,
bool  excluded,
unsigned int *  hit,
unsigned int *  excludes,
unsigned int *  total
 

Calculates combination logic statistics for a single expression tree.

Recursively traverses the specified expression tree, recording the total number of logical combinations in the expression list and the number of combinations hit during the course of simulation. An expression can be considered for combinational coverage if the "measured" bit is set in the expression.

Parameters:
exp  Pointer to expression tree to traverse
ulid  Pointer to current underline ID
curr_depth  Current search depth in given expression tree
excluded  Specifies that this expression should be excluded for hit information because one or more of its parent expressions have been excluded
hit  Pointer to number of logical combinations hit during simulation
excludes  Pointer to number of excluded logical combinations
total  Pointer to total number of logical combinations

00334   { PROFILE(COMBINATION_GET_TREE_STATS);
00335 
00336   int num_hit = 0;  /* Number of expression value hits for the current expression */
00337   int tot_num;      /* Total number of combinations for the current expression */
00338 
00339   if( exp != NULL ) {
00340 
00341     /* Calculate excluded value for this expression */
00342     excluded |= ESUPPL_EXCLUDED( exp->suppl );
00343 
00344     /* Calculate children */
00345     combination_get_tree_stats( exp->left,  ulid, combination_calc_depth( exp, curr_depth, TRUE ),  excluded, hit, excludes, total );
00346     combination_get_tree_stats( exp->right, ulid, combination_calc_depth( exp, curr_depth, FALSE ), excluded, hit, excludes, total );
00347 
00348     if( ((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) ||
00349          (report_comb_depth == REPORT_VERBOSE) ||
00350          (report_comb_depth == REPORT_SUMMARY) ) {
00351 
00352       if( (EXPR_IS_MEASURABLE( exp ) == 1) && (ESUPPL_WAS_COMB_COUNTED( exp->suppl ) == 0) ) {
00353 
00354         if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ||
00355             ((exp->op != EXP_OP_AND) &&
00356              (exp->op != EXP_OP_LAND) &&
00357              (exp->op != EXP_OP_OR)   &&
00358              (exp->op != EXP_OP_LOR)) ||
00359              !allow_multi_expr ) {
00360 
00361           /* Calculate current expression combination coverage */
00362           if( (((exp->left != NULL) &&
00363                 (exp->op == exp->left->op)) ||
00364                ((exp->right != NULL) &&
00365                 (exp->op == exp->right->op))) &&
00366               ((exp->op == EXP_OP_AND)  ||
00367                (exp->op == EXP_OP_OR)   ||
00368                (exp->op == EXP_OP_LAND) ||
00369                (exp->op == EXP_OP_LOR)) && allow_multi_expr ) {
00370             combination_multi_expr_calc( exp, ulid, FALSE, excluded, hit, excludes, total );
00371           } else {
00372             if( !expression_is_static_only( exp ) ) {
00373               if( EXPR_IS_COMB( exp ) == 1 ) {
00374                 if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) {
00375                   if( report_bitwise ) {
00376                     tot_num = 3 * exp->value->width;
00377                     num_hit = vector_get_eval_abc_count( exp->value );
00378                   } else {
00379                     tot_num = 3;
00380                     num_hit = ESUPPL_WAS_FALSE( exp->left->suppl )  + 
00381                               ESUPPL_WAS_FALSE( exp->right->suppl ) +
00382                               exp->suppl.part.eval_11;
00383                   }
00384                 } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) {
00385                   if( report_bitwise ) {
00386                     tot_num = 3 * exp->value->width;
00387                     num_hit = vector_get_eval_abc_count( exp->value );
00388                   } else {
00389                     tot_num = 3;
00390                     num_hit = ESUPPL_WAS_TRUE( exp->left->suppl )  +
00391                               ESUPPL_WAS_TRUE( exp->right->suppl ) +
00392                               exp->suppl.part.eval_00;
00393                   }
00394                 } else {
00395                   if( report_bitwise ) {
00396                     tot_num = 4 * exp->value->width;
00397                     num_hit = vector_get_eval_abcd_count( exp->value );
00398                   } else {
00399                     tot_num = 4;
00400                     num_hit = exp->suppl.part.eval_00 +
00401                               exp->suppl.part.eval_01 +
00402                               exp->suppl.part.eval_10 +
00403                               exp->suppl.part.eval_11;
00404                   }
00405                 }
00406                 *total += tot_num;
00407                 if( excluded ) {
00408                   *hit      += tot_num;
00409                   *excludes += tot_num;
00410                 } else {
00411                   *hit += num_hit;
00412                 }
00413                 if( (num_hit != tot_num) && (exp->ulid == -1) && !combination_is_expr_multi_node( exp ) ) {
00414                   exp->ulid = *ulid;
00415                   (*ulid)++;
00416                 }
00417               } else if( EXPR_IS_EVENT( exp ) == 1 ) {
00418                 (*total)++;
00419                 num_hit = ESUPPL_WAS_TRUE( exp->suppl );
00420                 if( excluded ) {
00421                   (*hit)++;
00422                   (*excludes)++;
00423                 } else {
00424                   *hit += num_hit;
00425                 }
00426                 if( (num_hit != 1) && (exp->ulid == -1) && !combination_is_expr_multi_node( exp ) ) {
00427                   exp->ulid = *ulid;
00428                   (*ulid)++;
00429                 }
00430               } else {
00431                 if( report_bitwise ) {
00432                   *total  = *total + (2 * exp->value->width);
00433                   num_hit = vector_get_eval_ab_count( exp->value );
00434                 } else {
00435                   *total  = *total + 2;
00436                   num_hit = ESUPPL_WAS_TRUE( exp->suppl ) + ESUPPL_WAS_FALSE( exp->suppl );
00437                 }
00438                 if( excluded ) {
00439                   *hit      += 2;
00440                   *excludes += 2;
00441                 } else {
00442                   *hit += num_hit;
00443                 }
00444                 if( (num_hit != 2) && (exp->ulid == -1) && !combination_is_expr_multi_node( exp ) ) {
00445                   exp->ulid = *ulid;
00446                   (*ulid)++;
00447                 }
00448               }
00449             }
00450           }
00451 
00452         }
00453 
00454       }
00455 
00456     }
00457 
00458     /* Consider this expression to be counted */
00459     exp->suppl.part.comb_cntd = 1;
00460 
00461   }
00462 
00463   PROFILE_END;
00464 
00465 }

bool combination_instance_summary FILE *  ofile,
funit_inst root,
char *  parent,
int *  hits,
int *  total
[static]
 

Returns:
Returns TRUE if combinations were found to be missed; otherwise, returns FALSE.
Outputs summarized results of the combinational logic coverage per functional unit instance to the specified output stream. Summarized results are printed as percentages based on the number of combinations hit during simulation divided by the total number of expression combinations possible in the design. An expression is said to be measurable for combinational coverage if it evaluates to a value of 0 or 1.
Parameters:
ofile  Pointer to file to output results to
root  Pointer to node in instance tree to evaluate
parent  Name of parent instance name
hits  Pointer to accumulated number of combinations hit
total  Pointer to accumulated number of total combinations in design

00637   { PROFILE(COMBINATION_INSTANCE_SUMMARY);
00638 
00639   funit_inst* curr;                /* Pointer to current child functional unit instance of this node */
00640   char        tmpname[4096];       /* Temporary name holder of instance */
00641   char*       pname;               /* Printable version of instance name */
00642   bool        miss_found = FALSE;  /* Set to TRUE if a logical combination was missed */
00643 
00644   assert( root != NULL );
00645   assert( root->stat != NULL );
00646 
00647   /* Generate printable version of instance name */
00648   pname = scope_gen_printable( root->name );
00649 
00650   if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) {
00651     strcpy( tmpname, parent );
00652   } else if( strcmp( parent, "*" ) == 0 ) {
00653     strcpy( tmpname, pname );
00654   } else {
00655     unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent, obf_inst( pname ) );
00656     assert( rv < 4096 );
00657   }
00658 
00659   free_safe( pname, (strlen( pname ) + 1) );
00660 
00661   if( (root->funit != NULL) && root->stat->show && !funit_is_unnamed( root->funit ) &&
00662       ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit )) ) {
00663 
00664     miss_found |= combination_display_instance_summary( ofile, tmpname, root->stat->comb_hit, root->stat->comb_total );
00665 
00666     /* Update accumulated information */
00667     *hits  += root->stat->comb_hit;
00668     *total += root->stat->comb_total;
00669 
00670   }
00671 
00672   /* If this is an assertion module, don't output any further */
00673   if( (info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit ) ) {
00674 
00675     curr = root->child_head;
00676     while( curr != NULL ) {
00677       miss_found |= combination_instance_summary( ofile, curr, tmpname, hits, total );
00678       curr = curr->next;
00679     }
00680 
00681   }
00682 
00683   PROFILE_END;
00684 
00685   return( miss_found );
00686 
00687 }

void combination_instance_verbose FILE *  ofile,
funit_inst root,
char *  parent
[static]
 

Exceptions:
anonymous combination_display_verbose combination_instance_verbose
Outputs the verbose coverage report for the specified functional unit instance to the specified output stream.
Parameters:
ofile  Pointer to file to output results to
root  Pointer to current functional unit instance to evaluate
parent  Name of parent instance

02651   { PROFILE(COMBINATION_INSTANCE_VERBOSE);
02652 
02653   funit_inst* curr_inst;      /* Pointer to current instance being evaluated */
02654   char        tmpname[4096];  /* Temporary name holder of instance */
02655   char*       pname;          /* Printable version of instance name */
02656 
02657   assert( root != NULL );
02658 
02659   /* Get printable version of instance name */
02660   pname = scope_gen_printable( root->name );
02661 
02662   if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) {
02663     strcpy( tmpname, parent );
02664   } else if( strcmp( parent, "*" ) == 0 ) {
02665     strcpy( tmpname, pname );
02666   } else {
02667     unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent, pname );
02668     assert( rv < 4096 );
02669   }
02670 
02671   free_safe( pname, (strlen( pname ) + 1) );
02672 
02673   if( (root->funit != NULL) && !funit_is_unnamed( root->funit ) &&
02674       (((root->stat->comb_hit < root->stat->comb_total) && !report_covered) ||
02675        ((root->stat->comb_hit > 0) && report_covered) ||
02676        ((root->stat->comb_excluded > 0) && report_exclusions)) ) {
02677 
02678     /* Get printable version of functional unit name */
02679     pname = scope_gen_printable( funit_flatten_name( root->funit ) );
02680 
02681     fprintf( ofile, "\n" );
02682     switch( root->funit->type ) {
02683       case FUNIT_MODULE       :  fprintf( ofile, "    Module: " );       break;
02684       case FUNIT_ANAMED_BLOCK :
02685       case FUNIT_NAMED_BLOCK  :  fprintf( ofile, "    Named Block: " );  break;
02686       case FUNIT_AFUNCTION    :
02687       case FUNIT_FUNCTION     :  fprintf( ofile, "    Function: " );     break;
02688       case FUNIT_ATASK        :
02689       case FUNIT_TASK         :  fprintf( ofile, "    Task: " );         break;
02690       default                 :  fprintf( ofile, "    UNKNOWN: " );      break;
02691     }
02692     fprintf( ofile, "%s, File: %s, Instance: %s\n", pname, obf_file( root->funit->filename ), tmpname );
02693     fprintf( ofile, "    -------------------------------------------------------------------------------------------------------------\n" );
02694 
02695     free_safe( pname, (strlen( pname ) + 1) );
02696 
02697     if( ((root->stat->comb_hit < root->stat->comb_total) && !report_covered) ||
02698         ((root->stat->comb_hit > 0) && report_covered && (!report_exclusions || (root->stat->comb_hit > root->stat->comb_excluded))) ) {
02699       combination_display_verbose( ofile, root->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) );
02700     }
02701     if( report_exclusions && (root->stat->comb_excluded > 0) ) {
02702       combination_reset_counted_exprs( root->funit );
02703       combination_display_verbose( ofile, root->funit, RPT_TYPE_EXCL );
02704     }
02705 
02706   }
02707 
02708   curr_inst = root->child_head;
02709   while( curr_inst != NULL ) {
02710     combination_instance_verbose( ofile, curr_inst, tmpname );
02711     curr_inst = curr_inst->next;
02712   }
02713 
02714   PROFILE_END;
02715 
02716 }

bool combination_is_expr_multi_node expression exp  )  [static]
 

Returns:
Returns TRUE if the specified expression is part of a multi-value expression tree; otherwise, returns FALSE.
Checks the specified expression to see if it is a part of a multi-value expression tree. If the expression is part of a tree, returns a value of TRUE; otherwise, returns a value of FALSE. This function is used when determining if a non-multi-value expression should be assigned an underline ID (it should if the expression is not part of a multi-value expression tree) or be assigned one later (if the expression is part of a multi-value expression tree -- the ID will be assigned to it when the multi-value expression tree is assigned underline IDs.
Parameters:
exp  Pointer to expression to evaluate

00296   { PROFILE(COMBINATION_IS_EXPR_MULTI_NODE);
00297 
00298   bool retval = (exp != NULL) &&
00299                 (ESUPPL_IS_ROOT( exp->suppl ) == 0) && 
00300                 (exp->parent->expr->left  != NULL) &&
00301                 (exp->parent->expr->right != NULL) &&
00302                 ( ( (exp->parent->expr->right->id == exp->id) &&
00303                     (exp->parent->expr->left->ulid == -1) ) ||
00304                   (exp->parent->expr->left->id == exp->id) ) &&
00305                 ( (exp->parent->expr->op == EXP_OP_AND)  ||
00306                   (exp->parent->expr->op == EXP_OP_LAND) ||
00307                   (exp->parent->expr->op == EXP_OP_OR)   ||
00308                   (exp->parent->expr->op == EXP_OP_LOR) ) &&
00309                 ( ( (ESUPPL_IS_ROOT( exp->parent->expr->suppl ) == 0) &&
00310                     (exp->parent->expr->op == exp->parent->expr->parent->expr->op) ) ||
00311                   (exp->parent->expr->left->op == exp->parent->expr->op) );
00312 
00313   PROFILE_END;
00314 
00315   return( retval );
00316 
00317 }

void combination_list_missed FILE *  ofile,
expression exp,
unsigned int  curr_depth,
func_unit funit,
bool  show_exclusions
[static]
 

Describe which combinations were not hit for all subexpressions in the specified expression tree. We display the value of missed combinations by displaying the combinations of the children expressions that were not run during simulation.

Parameters:
ofile  Pointer to file to output results to
exp  Pointer to expression tree to evaluate
curr_depth  Specifies current depth of expression tree
funit  Pointer to current functional unit
show_exclusions  Set to TRUE to display exclusions

02472   { PROFILE(COMBINATION_LIST_MISSED);
02473 
02474   char** info;       /* String array containing combination coverage information for this expression */
02475   int    info_size;  /* Specifies the number of valid entries in the info array */
02476   int    i;          /* Loop iterator */
02477   
02478   if( exp != NULL ) {
02479 
02480     exclude_reason* er;
02481     
02482     combination_list_missed( ofile, exp->left,  combination_calc_depth( exp, curr_depth, TRUE ),  funit, show_exclusions );
02483     combination_list_missed( ofile, exp->right, combination_calc_depth( exp, curr_depth, FALSE ), funit, show_exclusions );
02484 
02485     /* Get coverage information for this expression */
02486     combination_get_missed_expr( &info, &info_size, exp, curr_depth, show_exclusions );
02487 
02488     /* If there was any coverage information for this expression, output it to the specified output stream */
02489     if( info_size > 0 ) {
02490 
02491       for( i=0; i<info_size; i++ ) {
02492 
02493         fprintf( ofile, "%s\n", info[i] );
02494         free_safe( info[i], (strlen( info[i] ) + 1) );
02495 
02496       }
02497 
02498       /* Output the exclusion reason information, if it exists */
02499       if( report_exclusions && (er = exclude_find_exclude_reason( 'E', exp->id, funit )) != NULL ) {
02500         if( flag_output_exclusion_ids ) {
02501           report_output_exclusion_reason( ofile, (14 + (db_get_exclusion_id_size() - 1)), er->reason, TRUE );
02502         } else {
02503           report_output_exclusion_reason( ofile, 10, er->reason, TRUE );
02504         }
02505       }
02506 
02507       fprintf( ofile, "\n" );
02508 
02509       free_safe( info, (sizeof( char* ) * info_size) );
02510 
02511     }
02512 
02513   }
02514 
02515   PROFILE_END;
02516 
02517 }

void combination_multi_expr_calc expression exp,
int *  ulid,
bool  ul,
bool  excluded,
unsigned int *  hit,
unsigned int *  excludes,
unsigned int *  total
[static]
 

Parses the specified expression tree, calculating the hit and total values of all sub-expressions that are the same operation types as their left children.

Parameters:
exp  Pointer to expression to calculate hit and total of multi-expression subtrees
ulid  Pointer to current underline ID
ul  If TRUE, parent expressions were found to be missing so force the underline
excluded  If TRUE, parent expressions were found to be excluded
hit  Pointer to value containing number of hit expression values in this expression
excludes  Pointer to value containing number of excluded combinational expressions
total  Pointer to value containing total number of expression values in this expression

00201   { PROFILE(COMBINATION_MULTI_EXPR_CALC);
00202 
00203   bool and_op;  /* Specifies if current expression is an AND or LAND operation */
00204 
00205   if( exp != NULL ) {
00206 
00207     /* Calculate this expression's exclusion */
00208     excluded |= ESUPPL_EXCLUDED( exp->suppl );
00209 
00210     /* Figure out if this is an AND/LAND operation */
00211     and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND);
00212 
00213     /* Decide if our expression requires that this sequence gets underlined */
00214     if( !ul ) {
00215       ul = combination_does_multi_exp_need_ul( exp );
00216     }
00217 
00218     if( (exp->left != NULL) && (exp->op != exp->left->op) ) {
00219       if( excluded ) {
00220         (*hit)++;
00221         (*excludes)++;
00222       } else {
00223         if( and_op ) {
00224           *hit += ESUPPL_WAS_FALSE( exp->left->suppl );
00225         } else {
00226           *hit += ESUPPL_WAS_TRUE( exp->left->suppl );
00227         }
00228       }
00229       if( (exp->left->ulid == -1) && ul ) { 
00230         exp->left->ulid = *ulid;
00231         (*ulid)++;
00232       }
00233       (*total)++;
00234     } else {
00235       combination_multi_expr_calc( exp->left, ulid, ul, excluded, hit, excludes, total );
00236     }
00237 
00238     if( (exp->right != NULL) && (exp->op != exp->right->op) ) {
00239       if( excluded ) {
00240         (*hit)++;
00241         (*excludes)++;
00242       } else {
00243         if( and_op ) {
00244           *hit += ESUPPL_WAS_FALSE( exp->right->suppl );
00245         } else {
00246           *hit += ESUPPL_WAS_TRUE( exp->right->suppl );
00247         }
00248       }
00249       if( (exp->right->ulid == -1) && ul ) {
00250         exp->right->ulid = *ulid;
00251         (*ulid)++;
00252       }
00253       (*total)++;
00254     } else {
00255       combination_multi_expr_calc( exp->right, ulid, ul, excluded, hit, excludes, total );
00256     }
00257 
00258     if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ) {
00259       if( excluded ) {
00260         (*hit)++;
00261         (*excludes)++;
00262       } else {
00263         if( and_op ) {
00264           *hit += exp->suppl.part.eval_11;
00265         } else {
00266           *hit += exp->suppl.part.eval_00;
00267         }
00268       }
00269       if( (exp->ulid == -1) && ul ) {
00270         exp->ulid = *ulid;
00271         (*ulid)++;
00272       }
00273       (*total)++;
00274     }
00275 
00276   }
00277 
00278   PROFILE_END;
00279 
00280 }

void combination_multi_expr_output char **  info,
char *  line1,
char *  line2,
char *  line3
[static]
 

Stores the information from line1, line2 and line3 in the string array info.

Parameters:
info  Pointer string to output report contents to
line1  First line of multi-variable expression output
line2  Second line of multi-variable expression output
line3  Third line of multi-variable expression output

02185   { PROFILE(COMBINATION_MULTI_EXPR_OUTPUT);
02186 
02187   int          start      = 0;
02188   int          i;
02189   int          len        = strlen( line1 );
02190   int          info_index = 2;
02191   unsigned int eid_size;
02192 
02193   if( flag_output_exclusion_ids ) {
02194     eid_size = db_get_exclusion_id_size();
02195   }
02196 
02197   for( i=0; i<len; i++ ) {
02198 
02199     if( (i + 1) == len ) {
02200 
02201       unsigned int rv;
02202       unsigned int slen1 = strlen( line1 + start ) + 9;
02203       unsigned int slen2 = strlen( line2 + start ) + 9;
02204       unsigned int slen3 = strlen( line3 + start ) + 9;
02205 
02206       if( flag_output_exclusion_ids ) {
02207         slen1 += (eid_size - 1) + 4;
02208         slen2 += (eid_size - 1) + 4;
02209         slen3 += (eid_size - 1) + 4;
02210       }
02211 
02212       info[info_index+0] = (char*)malloc_safe( slen1 );
02213       info[info_index+1] = (char*)malloc_safe( slen2 );
02214       info[info_index+2] = (char*)malloc_safe( slen3 );
02215 
02216       if( flag_output_exclusion_ids ) {
02217         char tmp[30];
02218         gen_char_string( tmp, ' ', ((eid_size - 1) + 4) );
02219         rv = snprintf( info[info_index+0], slen1, "%s        %s", tmp, (line1 + start) );
02220         assert( rv < slen1 );
02221         rv = snprintf( info[info_index+1], slen2, "%s        %s", tmp, (line2 + start) );
02222         assert( rv < slen2 );
02223         rv = snprintf( info[info_index+2], slen3, "%s        %s", tmp, (line3 + start) );
02224         assert( rv < slen3 );
02225       } else {
02226         rv = snprintf( info[info_index+0], slen1, "        %s", (line1 + start) );
02227         assert( rv < slen1 );
02228         rv = snprintf( info[info_index+1], slen2, "        %s", (line2 + start) );
02229         assert( rv < slen2 );
02230         rv = snprintf( info[info_index+2], slen3, "        %s", (line3 + start) );
02231         assert( rv < slen3 );
02232       }
02233 
02234     } else if( (line1[i] == '|') && ((i - start) >= line_width) ) {
02235 
02236       unsigned int rv;
02237       unsigned int slen1;
02238       unsigned int slen2;
02239       unsigned int slen3;
02240 
02241       line1[i] = '\0';
02242       line2[i] = '\0';
02243       line3[i] = '\0';
02244 
02245       slen1 = strlen( line1 + start ) + 10;
02246       slen2 = strlen( line2 + start ) + 10;
02247       slen3 = strlen( line3 + start ) + 11;
02248 
02249       if( flag_output_exclusion_ids ) {
02250         slen1 += (eid_size - 1) + 4;
02251         slen2 += (eid_size - 1) + 4;
02252         slen3 += (eid_size - 1) + 4;
02253       }
02254 
02255       info[info_index+0] = (char*)malloc_safe( slen1 );
02256       info[info_index+1] = (char*)malloc_safe( slen2 );
02257       info[info_index+2] = (char*)malloc_safe( slen3 );
02258 
02259       if( flag_output_exclusion_ids ) {
02260         char tmp[30];
02261         gen_char_string( tmp, ' ', ((eid_size - 1) + 4) );
02262         rv = snprintf( info[info_index+0], slen1, "%s        %s|",   tmp, (line1 + start) );
02263         assert( rv < slen1 );
02264         rv = snprintf( info[info_index+1], slen2, "%s        %s|",   tmp, (line2 + start) );
02265         assert( rv < slen2 );
02266         rv = snprintf( info[info_index+2], slen3, "%s        %s \n", tmp, (line3 + start) );
02267         assert( rv < slen3 );
02268       } else {
02269         rv = snprintf( info[info_index+0], slen1, "        %s|",   (line1 + start) );
02270         assert( rv < slen1 );
02271         rv = snprintf( info[info_index+1], slen2, "        %s|",   (line2 + start) );
02272         assert( rv < slen2 );
02273         rv = snprintf( info[info_index+2], slen3, "        %s \n", (line3 + start) );
02274         assert( rv < slen3 );
02275       }
02276 
02277       start       = i + 1;
02278       info_index += 3;
02279 
02280     }
02281 
02282   }
02283 
02284   PROFILE_END;
02285 
02286 }

int combination_multi_expr_output_length char *  line1  )  [static]
 

Returns:
Returns the number of lines required to store the multi-variable expression output contained in line1, line2, and line3.
Parameters:
line1  First line of multi-variable expression output

02155   { PROFILE(COMBINATION_MULTI_EXPR_OUTPUT_LENGTH);
02156 
02157   int start  = 0;
02158   int i;
02159   int len    = strlen( line1 );
02160   int length = 0;
02161 
02162   for( i=0; i<len; i++ ) {
02163     if( (i + 1) == len ) {
02164       length += 3;
02165     } else if( (line1[i] == '|') && ((i - start) >= line_width) ) {
02166       length += 3;
02167       start   = i + 1;
02168     }
02169   }
02170 
02171   PROFILE_END;
02172 
02173   return( length );
02174 
02175 }

void combination_multi_var_exprs char **  line1,
char **  line2,
char **  line3,
expression exp
[static]
 

Creates the verbose report information for a multi-variable expression, storing its output in the line1, line2, and line3 strings.

Parameters:
line1  Pointer to first line of multi-variable expression output
line2  Pointer to second line of multi-variable expression output
line3  Pointer to third line of multi-variable expression output
exp  Pointer to current expression to output

01980   { PROFILE(COMBINATION_MULTI_VAR_EXPRS);
01981 
01982   char*        left_line1  = NULL;
01983   char*        left_line2  = NULL;
01984   char*        left_line3  = NULL;
01985   char*        right_line1 = NULL;
01986   char*        right_line2 = NULL;
01987   char*        right_line3 = NULL;
01988   char         curr_id_str[20];
01989   unsigned int curr_id_str_len;
01990   unsigned int i;
01991   bool         and_op;
01992   unsigned int rv;                  /* Return value from snprintf calls */
01993 
01994   if( exp != NULL ) {
01995 
01996     and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND);
01997 
01998     /* If we have hit the left-most expression, start creating string here */
01999     if( (exp->left != NULL) && (exp->op != exp->left->op) ) {
02000 
02001       assert( exp->left->ulid != -1 );
02002       rv = snprintf( curr_id_str, 20, "%d", exp->left->ulid );
02003       assert( rv < 20 );
02004       curr_id_str_len = strlen( curr_id_str );
02005       left_line1 = (char*)malloc_safe( curr_id_str_len + 4 );
02006       left_line2 = (char*)malloc_safe( curr_id_str_len + 4 );
02007       left_line3 = (char*)malloc_safe( curr_id_str_len + 4 );
02008       rv = snprintf( left_line1, (curr_id_str_len + 4), " %s |", curr_id_str );
02009       assert( rv < (curr_id_str_len + 4) );
02010       for( i=0; i<(curr_id_str_len-1); i++ ) {
02011         curr_id_str[i] = '=';
02012       }
02013       curr_id_str[i] = '\0'; 
02014       if( and_op ) { 
02015         rv = snprintf( left_line2, (curr_id_str_len + 4), "=0%s=|", curr_id_str );
02016         assert( rv < (curr_id_str_len + 4) );
02017       } else { 
02018         rv = snprintf( left_line2, (curr_id_str_len + 4), "=1%s=|", curr_id_str );
02019         assert( rv < (curr_id_str_len + 4) );
02020       }
02021       for( i=0; i<(curr_id_str_len - 1); i++ ) {
02022         curr_id_str[i] = ' ';
02023       }
02024       curr_id_str[i] = '\0';
02025       if( and_op ) {
02026         rv = snprintf( left_line3, (curr_id_str_len + 4), " %c%s  ", ((ESUPPL_WAS_FALSE( exp->left->suppl ) == 1) ? ' ' : '*'), curr_id_str );
02027         assert( rv < (curr_id_str_len + 4) );
02028       } else {
02029         rv = snprintf( left_line3, (curr_id_str_len + 4), " %c%s  ", ((ESUPPL_WAS_TRUE( exp->left->suppl )  == 1) ? ' ' : '*'), curr_id_str );
02030         assert( rv < (curr_id_str_len + 4) );
02031       }
02032 
02033     } else {
02034 
02035       combination_multi_var_exprs( &left_line1, &left_line2, &left_line3, exp->left );
02036 
02037     }
02038 
02039     /* Get right-side information */
02040     if( (exp->right != NULL) && (exp->op != exp->right->op) ) {
02041 
02042       assert( exp->right->ulid != -1 );
02043       rv = snprintf( curr_id_str, 20, "%d", exp->right->ulid );
02044       assert( rv < 20 );
02045       curr_id_str_len = strlen( curr_id_str );
02046       right_line1 = (char*)malloc_safe( curr_id_str_len + 4 );
02047       right_line2 = (char*)malloc_safe( curr_id_str_len + 4 );
02048       right_line3 = (char*)malloc_safe( curr_id_str_len + 4 );
02049       rv = snprintf( right_line1, (curr_id_str_len + 4), " %s |", curr_id_str );
02050       assert( rv < (curr_id_str_len + 4) );
02051       for( i=0; i<(curr_id_str_len-1); i++ ) {
02052         curr_id_str[i] = '=';
02053       }
02054       curr_id_str[i] = '\0';
02055       if( and_op ) {
02056         rv = snprintf( right_line2, (curr_id_str_len + 4), "=0%s=|", curr_id_str );
02057         assert( rv < (curr_id_str_len + 4) );
02058       } else {
02059         rv = snprintf( right_line2, (curr_id_str_len + 4), "=1%s=|", curr_id_str );
02060         assert( rv < (curr_id_str_len + 4) );
02061       }
02062       for( i=0; i<(curr_id_str_len - 1); i++ ) {
02063         curr_id_str[i] = ' ';
02064       }
02065       curr_id_str[i] = '\0';
02066       if( and_op ) {
02067         rv = snprintf( right_line3, (curr_id_str_len + 4), " %c%s  ", ((ESUPPL_WAS_FALSE( exp->right->suppl ) == 1) ? ' ' : '*'), curr_id_str );
02068         assert( rv < (curr_id_str_len + 4) );
02069       } else {
02070         rv = snprintf( right_line3, (curr_id_str_len + 4), " %c%s  ", ((ESUPPL_WAS_TRUE( exp->right->suppl )  == 1) ? ' ' : '*'), curr_id_str );
02071         assert( rv < (curr_id_str_len + 4) );
02072       }
02073 
02074     } else {
02075 
02076       combination_multi_var_exprs( &right_line1, &right_line2, &right_line3, exp->right );
02077 
02078     }
02079 
02080     if( left_line1 != NULL ) {
02081       if( right_line1 != NULL ) {
02082         unsigned int slen1 = strlen( left_line1 ) + strlen( right_line1 ) + 1;
02083         unsigned int slen2 = strlen( left_line2 ) + strlen( right_line2 ) + 1;
02084         unsigned int slen3 = strlen( left_line3 ) + strlen( right_line3 ) + 1;
02085         *line1 = (char*)malloc_safe( slen1 );
02086         *line2 = (char*)malloc_safe( slen2 );
02087         *line3 = (char*)malloc_safe( slen3 );
02088         rv = snprintf( *line1, slen1, "%s%s", left_line1, right_line1 );
02089         assert( rv < slen1 );
02090         rv = snprintf( *line2, slen2, "%s%s", left_line2, right_line2 );
02091         assert( rv < slen2 );
02092         rv = snprintf( *line3, slen3, "%s%s", left_line3, right_line3 );
02093         assert( rv < slen3 );
02094         free_safe( left_line1, (strlen( left_line1 ) + 1) );
02095         free_safe( left_line2, (strlen( left_line2 ) + 1) );
02096         free_safe( left_line3, (strlen( left_line3 ) + 1) );
02097         free_safe( right_line1, (strlen( right_line1 ) + 1) );
02098         free_safe( right_line2, (strlen( right_line2 ) + 1) );
02099         free_safe( right_line3, (strlen( right_line3 ) + 1) );
02100       } else {
02101         *line1 = left_line1;
02102         *line2 = left_line2;
02103         *line3 = left_line3;
02104       }
02105     } else {
02106       assert( right_line1 != NULL );
02107       *line1 = right_line1;
02108       *line2 = right_line2;
02109       *line3 = right_line3;
02110     }
02111 
02112     /* If we are the root, output all value */
02113     if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ) {
02114       unsigned int slen1 = strlen( *line1 ) + 5;
02115       unsigned int slen2 = strlen( *line2 ) + 6;
02116       unsigned int slen3 = strlen( *line3 ) + 6;
02117       left_line1 = *line1;
02118       left_line2 = *line2;
02119       left_line3 = *line3;
02120       *line1     = (char*)malloc_safe( slen1 );
02121       *line2     = (char*)malloc_safe( slen2 );
02122       *line3     = (char*)malloc_safe( slen3 );
02123       if( and_op ) {
02124         rv = snprintf( *line1, slen1, "%s All",   left_line1 );
02125         assert( rv < slen1 );
02126         rv = snprintf( *line2, slen2, "%s==1==",  left_line2 );
02127         assert( rv < slen2 );
02128         rv = snprintf( *line3, slen3, "%s  %c  ", left_line3, ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') );
02129         assert( rv < slen3 );
02130       } else {
02131         rv = snprintf( *line1, slen1, "%s All",   left_line1 );
02132         assert( rv < slen1 );
02133         rv = snprintf( *line2, slen2, "%s==0==",  left_line2 );
02134         assert( rv < slen2 );
02135         rv = snprintf( *line3, slen3, "%s  %c  ", left_line3, ((exp->suppl.part.eval_00 == 1) ? ' ' : '*') );
02136         assert( rv < slen3 );
02137       }
02138       free_safe( left_line1, (strlen( left_line1 ) + 1) );
02139       free_safe( left_line2, (strlen( left_line2 ) + 1) );
02140       free_safe( left_line3, (strlen( left_line3 ) + 1) );
02141     }
02142 
02143   }
02144 
02145   PROFILE_END;
02146 
02147 }

void combination_multi_vars char ***  info,
int *  info_size,
expression exp,
bool  show_excluded
[static]
 

Displays the missed combinational sequences for the specified expression to the specified output stream in tabular form.

Parameters:
info  Pointer to character array containing coverage information to output
info_size  Pointer to integer containing number of valid array entries in info
exp  Pointer to top-level AND/OR expression to evaluate
show_excluded  Set to TRUE to output expression if it is excluded

02297   { PROFILE(COMBINATION_MULTI_VARS);
02298 
02299   int          ulid      = 1;
02300   unsigned int hit       = 0;
02301   unsigned int excluded  = 0;
02302   unsigned int total     = 0;
02303   char*        line1     = NULL;
02304   char*        line2     = NULL;
02305   char*        line3     = NULL;
02306   char         tmp[20];
02307   unsigned int line_size = 1;
02308 
02309   /* Only output this expression if we are missing coverage. */
02310   if( exp->ulid != -1 ) {
02311 
02312     /* Calculate hit and total values for this sub-expression */
02313     combination_multi_expr_calc( exp, &ulid, FALSE, FALSE, &hit, &excluded, &total );
02314 
02315     if( (hit != total) || (exp->suppl.part.excluded && show_excluded) ) {
02316 
02317       unsigned int rv;
02318       unsigned int slen1;
02319       unsigned int slen2;
02320       unsigned int slen3;
02321       unsigned int eid_size;
02322 
02323       if( flag_output_exclusion_ids ) {
02324         eid_size = db_get_exclusion_id_size();
02325       }
02326 
02327       /* Gather report output for this expression */
02328       combination_multi_var_exprs( &line1, &line2, &line3, exp );
02329 
02330       /* Get the lengths of the original string lengths -- these strings will be possibly altered by combination_multi_expr_output */
02331       slen1 = strlen( line1 ) + 1;
02332       slen2 = strlen( line2 ) + 1;
02333       slen3 = strlen( line3 ) + 1;
02334 
02335       /* Calculate the array needed to store the output information and allocate this memory */
02336       *info_size = combination_multi_expr_output_length( line1 ) + 2;
02337       *info      = (char**)malloc_safe( sizeof( char* ) * (*info_size) );
02338 
02339       /* Calculate needed line length */
02340       rv = snprintf( tmp, 20, "%u", hit );
02341       assert( rv < 20 );
02342       line_size += strlen( tmp );
02343       rv = snprintf( tmp, 20, "%u", total );
02344       assert( rv < 20 );
02345       line_size += strlen( tmp );
02346       rv = snprintf( tmp, 20, "%d", exp->ulid );
02347       assert( rv < 20 );
02348       line_size += strlen( tmp );
02349       line_size += 25;                   /* Number of additional characters in line below */
02350       if( flag_output_exclusion_ids ) {
02351         line_size += (eid_size - 1) + 4;
02352       }
02353       (*info)[0] = (char*)malloc_safe( line_size );
02354     
02355       if( flag_output_exclusion_ids ) {
02356         char* tmp;
02357         char  spaces[30];
02358         int   size;
02359         rv = snprintf( (*info)[0], line_size, "        (%s)  Expression %d   (%u/%u)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, total );
02360         assert( rv < line_size );
02361         switch( exp->op ) {
02362           case EXP_OP_AND  :  tmp = strdup_safe( "        ^^^^^^^^^^^^^ - &" );   break;
02363           case EXP_OP_OR   :  tmp = strdup_safe( "        ^^^^^^^^^^^^^ - |" );   break;
02364           case EXP_OP_LAND :  tmp = strdup_safe( "        ^^^^^^^^^^^^^ - &&" );  break;
02365           case EXP_OP_LOR  :  tmp = strdup_safe( "        ^^^^^^^^^^^^^ - ||" );  break;
02366           default          :  break;
02367         }
02368         size = strlen( tmp ) + (eid_size - 1) + 5;
02369         gen_char_string( spaces, ' ', (eid_size - 1) );
02370         (*info)[1] = (char*)malloc_safe( size );
02371         rv = snprintf( (*info)[1], size, "%s    %s", spaces, tmp );
02372         assert( rv < size );
02373         free_safe( tmp, (strlen( tmp ) + 1) );
02374       } else {
02375         rv = snprintf( (*info)[0], line_size, "        Expression %d   (%u/%u)", exp->ulid, hit, total );
02376         assert( rv < line_size );
02377         switch( exp->op ) {
02378           case EXP_OP_AND  :  (*info)[1] = strdup_safe( "        ^^^^^^^^^^^^^ - &" );   break;
02379           case EXP_OP_OR   :  (*info)[1] = strdup_safe( "        ^^^^^^^^^^^^^ - |" );   break;
02380           case EXP_OP_LAND :  (*info)[1] = strdup_safe( "        ^^^^^^^^^^^^^ - &&" );  break;
02381           case EXP_OP_LOR  :  (*info)[1] = strdup_safe( "        ^^^^^^^^^^^^^ - ||" );  break;
02382           default          :  break;
02383         }
02384       }
02385 
02386       /* Output the lines paying attention to the current line width */
02387       combination_multi_expr_output( *info, line1, line2, line3 );
02388 
02389       free_safe( line1, slen1 );
02390       free_safe( line2, slen2 );
02391       free_safe( line3, slen3 );
02392 
02393     }
02394 
02395   }
02396 
02397   PROFILE_END;
02398 
02399 }

void combination_output_expr expression expr,
unsigned int  curr_depth,
int *  any_missed,
int *  any_measurable,
int *  any_excluded,
int *  all_excluded
[static]
 

Recursively traverses specified expression tree, returning TRUE if an expression is found that has not received 100% coverage for combinational logic.

Parameters:
expr  Pointer to root of expression tree to search
curr_depth  Specifies current depth of expression tree
any_missed  Pointer to indicate if any subexpressions were missed in the specified expression
any_measurable  Pointer to indicate if any subexpressions were measurable in the specified expression
any_excluded  Pointer to indicate if any subexpressions were excluded
all_excluded  Pointer to indicate if all subexpressions that can be excluded are

02531   { PROFILE(COMBINATION_OUTPUT_EXPR);
02532 
02533   if( (expr != NULL) && (ESUPPL_WAS_COMB_COUNTED( expr->suppl ) == 1) ) {
02534 
02535     expr->suppl.part.comb_cntd = 0;
02536 
02537     combination_output_expr( expr->right, combination_calc_depth( expr, curr_depth, FALSE ), any_missed, any_measurable, any_excluded, all_excluded );
02538     combination_output_expr( expr->left,  combination_calc_depth( expr, curr_depth, TRUE ),  any_missed, any_measurable, any_excluded, all_excluded );
02539 
02540     if( ((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) ||
02541          (report_comb_depth == REPORT_VERBOSE) ) {
02542  
02543       if( expr->ulid != -1 ) {
02544         *any_missed = 1;
02545       }
02546       if( (EXPR_IS_MEASURABLE( expr ) == 1) && !expression_is_static_only( expr ) ) {
02547         if( ESUPPL_EXCLUDED( expr->suppl ) == 0 ) {
02548           *any_measurable = 1;
02549           if( expr->ulid != -1 ) {
02550             *all_excluded = 0;
02551           }
02552         } else {
02553           *any_excluded = 1;
02554           *all_excluded = 1;
02555         }
02556       }
02557 
02558     }
02559 
02560   }
02561 
02562   PROFILE_END;
02563 
02564 }

void combination_parenthesize bool  parenthesis,
const char *  pre_code_format,
char **  new_code_format,
unsigned int *  code_format_size
[static]
 

Parenthesizes the code format and code format size variables.

00855   { PROFILE(COMBINATION_PARENTHESIZE);
00856 
00857   if( parenthesis ) {
00858 
00859     /* Create the new code format string with spacing for the parenthesis */
00860     unsigned int rv = snprintf( *new_code_format, 300, " %s ", pre_code_format );
00861     assert( rv < 300 );
00862 
00863     /* Update the code format size */
00864     *code_format_size += 2;
00865 
00866   } else {
00867 
00868     strcpy( *new_code_format, pre_code_format );
00869 
00870   }
00871 
00872   PROFILE_END;
00873 
00874 }

char* combination_prep_line char *  line,
int  start,
int  len
[static]
 

Returns:
Returns a newly allocated string that contains the underline information for the current line. If there is no underline information to return, a value of NULL is returned.
Formats the specified underline line to line wrap according to the generated code. This function must be called after the underline lines have been calculated prior to being output to the ASCII report or the GUI.
Parameters:
line  Line containing underlines that needs to be reformatted for line wrap
start  Starting index in line to take underline information from
len  Number of characters to use for the current line

01390   { PROFILE(COMBINATION_PREP_LINE);
01391 
01392   char* str;                /* Prepared line to return */
01393   char* newstr;             /* Prepared line to return */
01394   int   str_size;           /* Allocated size of str */
01395   int   exp_id;             /* Expression ID of current line */
01396   int   chars_read;         /* Number of characters read from sscanf function */
01397   int   i;                  /* Loop iterator */
01398   int   curr_index;         /* Index current character in str to set */
01399   bool  line_ip   = FALSE;  /* Specifies if a line is currently in progress */
01400   bool  line_seen = FALSE;  /* Specifies that a line has been seen for this line */
01401   int   start_ul  = 0;      /* Index of starting underline */
01402 
01403   /* Allocate memory for string to return */
01404   str_size = len + 2;
01405   str      = (char*)malloc_safe( str_size );
01406 
01407   i          = 0;
01408   curr_index = 0;
01409 
01410   while( i < (start + len) ) {
01411    
01412     if( *(line + i) == '|' ) {
01413       if( i >= start ) {
01414         line_seen = TRUE;
01415       }
01416       if( !line_ip ) {
01417         line_ip  = TRUE;
01418         start_ul = i;
01419         if( sscanf( (line + i + 1), "%d%n", &exp_id, &chars_read ) != 1 ) {
01420           assert( 0 == 1 );
01421         } else {
01422           i += chars_read;
01423         }
01424       } else {
01425         line_ip = FALSE;
01426         if( i >= start ) {
01427           if( start_ul >= start ) {
01428             combination_draw_centered_line( (str + curr_index), ((i - start_ul) + 1), exp_id, TRUE,  TRUE );
01429             curr_index += (i - start_ul) + 1;
01430           } else {
01431             combination_draw_centered_line( (str + curr_index), ((i - start) + 1), exp_id, FALSE, TRUE );
01432             curr_index += (i - start) + 1;
01433           }
01434         }
01435       }
01436     } else {
01437       if( i >= start ) {
01438         if( *(line + i) == '-' ) {
01439           line_seen = TRUE;
01440         } else {
01441           str[curr_index] = *(line + i);
01442           curr_index++;
01443         }
01444       }
01445     }
01446 
01447     i++;
01448 
01449   }
01450 
01451   if( line_ip ) {
01452     /* If our pointer exceeded the allotted size, resize the str to fit */
01453     if( i > (start + len) ) {
01454       str      = (char*)realloc_safe( str, str_size, (len + 2 + (i - (start + len))) );
01455       str_size = (len + 2 + (i - (start + len)));
01456     }
01457     if( start_ul >= start ) {
01458       combination_draw_centered_line( (str + curr_index), ((i - start_ul) + 1), exp_id, TRUE,  FALSE );
01459       curr_index += (i - start_ul) + 1;
01460     } else {
01461       combination_draw_centered_line( (str + curr_index), ((i - start) + 1), exp_id, FALSE, FALSE );
01462       curr_index += (i - start) + 1;
01463     }
01464   }
01465 
01466   /* If we didn't see any underlines here, return NULL */
01467   if( !line_seen ) {
01468     newstr = NULL;
01469   } else {
01470     str[curr_index] = '\0';
01471     newstr = strdup_safe( str );
01472   }
01473 
01474   /* The str may be a bit oversized, so we copied it and now free it here (where we know its allocated size) */
01475   free_safe( str, str_size );
01476 
01477   PROFILE_END;
01478 
01479   return( newstr );
01480 
01481 }

void combination_report FILE *  ofile,
bool  verbose
 

Generates report output for combinational logic coverage.

Exceptions:
anonymous combination_funit_verbose combination_instance_verbose
After the design is read into the functional unit hierarchy, parses the hierarchy by functional unit, reporting the combinational logic coverage for each functional unit encountered. The parent functional unit will specify its own combinational logic coverage along with a total combinational logic coverage including its children.
Parameters:
ofile  Pointer to file to output results to
verbose  Specifies whether or not to provide verbose information

03045   { PROFILE(COMBINATION_REPORT);
03046 
03047   bool       missed_found = FALSE;  /* If set to TRUE, indicates combinations were missed */
03048   inst_link* instl;                 /* Pointer to current instance link */
03049   int        acc_hits     = 0;      /* Accumulated number of combinations hit */
03050   int        acc_total    = 0;      /* Accumulated number of combinations in design */
03051 
03052   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
03053   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   COMBINATIONAL LOGIC COVERAGE RESULTS   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
03054   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
03055 
03056   if( report_instance ) {
03057 
03058     fprintf( ofile, "                                                                            Logic Combinations\n" );
03059     fprintf( ofile, "Instance                                                              Hit/Miss/Total    Percent hit\n" );
03060     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03061 
03062     instl = db_list[curr_db]->inst_head;
03063     while( instl != NULL ) {
03064       missed_found |= combination_instance_summary( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*"), &acc_hits, &acc_total );
03065       instl = instl->next;
03066     }
03067     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03068     (void)combination_display_instance_summary( ofile, "Accumulated", acc_hits, acc_total );
03069     
03070     if( verbose && (missed_found || report_covered || report_exclusions) ) {
03071       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03072       instl = db_list[curr_db]->inst_head;
03073       while( instl != NULL ) {
03074         combination_instance_verbose( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*") );
03075         instl = instl->next;
03076       }
03077     }
03078 
03079   } else {
03080 
03081     fprintf( ofile, "                                                                            Logic Combinations\n" );
03082     fprintf( ofile, "Module/Task/Function                Filename                          Hit/Miss/Total    Percent hit\n" );
03083     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03084 
03085     missed_found = combination_funit_summary( ofile, db_list[curr_db]->funit_head, &acc_hits, &acc_total );
03086     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03087     (void)combination_display_funit_summary( ofile, "Accumulated", "", acc_hits, acc_total );
03088 
03089     if( verbose && (missed_found || report_covered || report_exclusions) ) {
03090       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
03091       combination_funit_verbose( ofile, db_list[curr_db]->funit_head );
03092     }
03093 
03094   }
03095 
03096   fprintf( ofile, "\n\n" );
03097 
03098   PROFILE_END;
03099 
03100 }

void combination_reset_counted_expr_tree expression exp  ) 
 

Resets combination counted bits in expression tree.

Recursively iterates through specified expression tree, clearing the combination counted bit in the supplemental field of each child expression. This functions needs to get called whenever the excluded bit of an expression is changed.

Parameters:
exp  Pointer to expression tree to reset

00508   { PROFILE(COMBINATION_RESET_COUNTED_EXPR_TREE);
00509 
00510   if( exp != NULL ) {
00511 
00512     exp->suppl.part.comb_cntd = 0;
00513 
00514     combination_reset_counted_expr_tree( exp->left );
00515     combination_reset_counted_expr_tree( exp->right );
00516 
00517   }
00518 
00519   PROFILE_END;
00520 
00521 }

void combination_reset_counted_exprs func_unit funit  )  [static]
 

Iterates through specified expression list, setting the combination counted bit in the supplemental field of each expression. This function needs to get called whenever a new module is picked by the GUI.

Parameters:
funit  Pointer to functional unit to reset

00474   { PROFILE(COMBINATION_RESET_COUNTED_EXPRS);
00475 
00476   exp_link*   expl;   /* Pointer to current expression list */
00477   funit_link* child;  /* Pointer to current child functional unit */
00478 
00479   assert( funit != NULL );
00480 
00481   /* Reset the comb_cntd bit in all expressions for the current functional unit */
00482   expl = funit->exp_head;
00483   while( expl != NULL ) {
00484     expl->exp->suppl.part.comb_cntd = 1;
00485     expl = expl->next;
00486   }
00487 
00488   /* Do the same for all children functional units that are unnamed */
00489   child = funit->tf_head;
00490   while( child != NULL ) {
00491     if( funit_is_unnamed( child->funit ) ) {
00492       combination_reset_counted_exprs( child->funit );
00493     }
00494     child = child->next;
00495   }
00496 
00497   PROFILE_END;
00498 
00499 }

void combination_two_vars char ***  info,
int *  info_size,
expression exp,
bool  show_excluded
[static]
 

Displays the missed combinational sequences for the specified expression to the specified output stream in tabular form.

Parameters:
info  Pointer to array of strings that will contain the coverage information for this expression
info_size  Pointer to integer containing number of elements in info array
exp  Pointer to expression to evaluate
show_excluded  If set to TRUE, displays the expression if it has been excluded

01738   { PROFILE(COMBINATION_TWO_VARS);
01739 
01740   int          hit;                               /* Number of combinations hit for this expression */
01741   int          total;                             /* Total number of combinations for this expression */
01742   char         tmp[20];                           /* Temporary string used for calculating line width */
01743   unsigned int length;                            /* Specifies the length of the current line */
01744   char*        op = exp_op_info[exp->op].op_str;  /* Operation string */
01745   int          lines;                             /* Specifies the number of lines needed to output this vector */
01746   unsigned int rv;                                /* Return value from snprintf calls */
01747 
01748   assert( exp != NULL );
01749 
01750   /* Verify that left child expression is valid for this operation */
01751   assert( exp->left != NULL );
01752 
01753   /* Verify that right child expression is valid for this operation */
01754   assert( exp->right != NULL );
01755 
01756   /* Get hit information */
01757   if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) {
01758     if( report_bitwise && (exp->value->width > 1) ) {
01759       lines = exp->value->width + 2;
01760       total = (3 * exp->value->width);
01761       hit   = vector_get_eval_abc_count( exp->value );
01762     } else {
01763       lines = 1;
01764       total = 3;
01765       hit   = ESUPPL_WAS_FALSE( exp->left->suppl ) + ESUPPL_WAS_FALSE( exp->right->suppl ) + exp->suppl.part.eval_11;
01766     }
01767   } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) {
01768     if( report_bitwise && (exp->value->width > 1) ) {
01769       lines = exp->value->width + 2;
01770       total = (3 * exp->value->width);
01771       hit   = vector_get_eval_abc_count( exp->value );
01772     } else {
01773       lines = 1;
01774       total = 3;
01775       hit   = ESUPPL_WAS_TRUE( exp->left->suppl ) + ESUPPL_WAS_TRUE( exp->right->suppl ) + exp->suppl.part.eval_00;
01776     }
01777   } else {
01778     if( report_bitwise && (exp->value->width > 1) ) {
01779       lines = exp->value->width + 2;
01780       total = (4 * exp->value->width);
01781       hit   = vector_get_eval_abcd_count( exp->value );
01782     } else {
01783       lines = 1;
01784       total = 4;
01785       hit   = exp->suppl.part.eval_00 +
01786               exp->suppl.part.eval_01 +
01787               exp->suppl.part.eval_10 +
01788               exp->suppl.part.eval_11;
01789     }
01790   }
01791 
01792   if( (hit != total) || (exp->suppl.part.excluded && show_excluded) ) {
01793 
01794     char         spaces[30];
01795     unsigned int eid_size;
01796 
01797     if( flag_output_exclusion_ids ) {
01798       eid_size = db_get_exclusion_id_size();
01799     }
01800 
01801     spaces[0] = '\0';
01802 
01803     assert( exp->ulid != -1 );
01804 
01805     /* Allocate memory for info array */
01806     *info_size = 4 + lines;
01807     *info      = (char**)malloc_safe( sizeof( char* ) * (*info_size) );
01808 
01809     /* Allocate lines and assign values */ 
01810     length = 26;
01811     rv = snprintf( tmp, 20, "%d", exp->ulid );  assert( rv < 20 );  length += strlen( tmp );
01812     rv = snprintf( tmp, 20, "%d", hit );        assert( rv < 20 );  length += strlen( tmp );
01813     rv = snprintf( tmp, 20, "%d", total );      assert( rv < 20 );  length += strlen( tmp );
01814     if( flag_output_exclusion_ids ) {
01815       length += (eid_size - 1) + 4;
01816       gen_char_string( spaces, ' ', ((eid_size - 1) + 4) );
01817     }
01818     (*info)[0] = (char*)malloc_safe( length );
01819     if( flag_output_exclusion_ids ) {
01820       rv = snprintf( (*info)[0], length, "        (%s)  Expression %d   (%d/%d)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, total );
01821     } else {
01822       rv = snprintf( (*info)[0], length, "        Expression %d   (%d/%d)", exp->ulid, hit, total );
01823     }
01824     assert( rv < length );
01825 
01826     length = 25 + strlen( op ) + strlen( spaces );
01827     (*info)[1] = (char*)malloc_safe( length );
01828     rv = snprintf( (*info)[1], length, "%s        ^^^^^^^^^^^^^ - %s", spaces, op );
01829     assert( rv < length );
01830 
01831     if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) {
01832 
01833       if( report_bitwise && (exp->value->width > 1) ) {
01834 
01835         unsigned int i;
01836  
01837         length = 30 + strlen( spaces );
01838         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s          Bit | LR | LR | LR ", spaces );  assert( rv < length );
01839         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        ======|=0-=|=-0=|=11=", spaces );  assert( rv < length );
01840         (*info)[5] = (char*)malloc_safe( length );  rv = snprintf( (*info)[5], length, "%s        ------|----|----|----", spaces );  assert( rv < length );
01841 
01842         length = 28 + strlen( spaces );
01843         (*info)[4] = (char*)malloc_safe( length );
01844         rv = snprintf( (*info)[4], length, "%s          All | %c    %c    %c", spaces,
01845                        (ESUPPL_WAS_FALSE( exp->left->suppl )  ? ' ' : '*'),
01846                        (ESUPPL_WAS_FALSE( exp->right->suppl ) ? ' ' : '*'),
01847                        ((exp->suppl.part.eval_11 > 0) ? ' ' : '*') );
01848         assert( rv < length );
01849         for( i=0; i<exp->value->width; i++ ) {
01850           (*info)[i+6] = (char*)malloc_safe( length );
01851           rv = snprintf( (*info)[i+6], length, "%s         %4u | %c    %c    %c", spaces, i,
01852                          ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'),
01853                          ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'),
01854                          ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*') );
01855           assert( rv < length );
01856         }
01857 
01858       } else {
01859 
01860         length = 23 + strlen( spaces );
01861         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s         LR | LR | LR ", spaces );  assert( rv < length );
01862         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        =0-=|=-0=|=11=", spaces );  assert( rv < length );
01863 
01864         length = 21 + strlen( spaces );
01865         (*info)[4] = (char*)malloc_safe( length );
01866         rv = snprintf( (*info)[4], length, "%s         %c    %c    %c", spaces,
01867                        (ESUPPL_WAS_FALSE( exp->left->suppl )  ? ' ' : '*'),
01868                        (ESUPPL_WAS_FALSE( exp->right->suppl ) ? ' ' : '*'),
01869                        ((exp->suppl.part.eval_11 > 0) ? ' ' : '*') );
01870         assert( rv < length );
01871 
01872       }
01873 
01874     } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) {
01875 
01876       if( report_bitwise && (exp->value->width > 1) ) {
01877 
01878         unsigned int i;
01879 
01880         length = 30 + strlen( spaces );
01881         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s          Bit | LR | LR | LR ", spaces );  assert( rv < length );
01882         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        ======|=1-=|=-1=|=00=", spaces );  assert( rv < length );
01883         (*info)[5] = (char*)malloc_safe( length );  rv = snprintf( (*info)[5], length, "%s        ------|----|----|----", spaces );  assert( rv < length );
01884 
01885         length = 28 + strlen( spaces );
01886         (*info)[4] = (char*)malloc_safe( length );
01887         rv = snprintf( (*info)[4], length, "%s          All | %c    %c    %c", spaces,
01888                        (ESUPPL_WAS_TRUE( exp->left->suppl )  ? ' ' : '*'),
01889                        (ESUPPL_WAS_TRUE( exp->right->suppl ) ? ' ' : '*'),
01890                        ((exp->suppl.part.eval_00 > 0) ? ' ' : '*') );
01891         assert( rv < length );
01892         for( i=0; i<exp->value->width; i++ ) {
01893           (*info)[i+6] = (char*)malloc_safe( length );
01894           rv = snprintf( (*info)[i+6], length, "%s         %4u | %c    %c    %c", spaces, i,
01895                          ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'),
01896                          ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'),
01897                          ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*') );
01898           assert( rv < length );
01899         }
01900 
01901       } else {
01902 
01903         length = 23 + strlen( spaces );
01904         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s         LR | LR | LR ", spaces );  assert( rv < length );
01905         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        =1-=|=-1=|=00=", spaces );  assert( rv < length );
01906 
01907         length = 21 + strlen( spaces );
01908         (*info)[4] = (char*)malloc_safe( length );
01909         rv = snprintf( (*info)[4], length, "%s         %c    %c    %c", spaces,
01910                        (ESUPPL_WAS_TRUE( exp->left->suppl )  ? ' ' : '*'),
01911                        (ESUPPL_WAS_TRUE( exp->right->suppl ) ? ' ' : '*'),
01912                        ((exp->suppl.part.eval_00 > 0) ? ' ' : '*') );
01913         assert( rv < length );
01914 
01915       }
01916 
01917     } else {
01918 
01919       if( report_bitwise && (exp->value->width > 1) ) {
01920 
01921         unsigned int i;
01922 
01923         length = 35 + strlen( spaces );
01924         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s          Bit | LR | LR | LR | LR ", spaces );  assert( rv < length );
01925         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        ======|=00=|=01=|=10=|=11=", spaces );  assert( rv < length );
01926         (*info)[5] = (char*)malloc_safe( length );  rv = snprintf( (*info)[5], length, "%s        ------|----|----|----|----", spaces );  assert( rv < length );
01927 
01928         length = 33 + strlen( spaces );
01929         (*info)[4] = (char*)malloc_safe( length );
01930         rv = snprintf( (*info)[4], length, "%s          All | %c    %c    %c    %c", spaces,
01931                        ((exp->suppl.part.eval_00 == 1) ? ' ' : '*'),
01932                        ((exp->suppl.part.eval_01 == 1) ? ' ' : '*'),
01933                        ((exp->suppl.part.eval_10 == 1) ? ' ' : '*'),
01934                        ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') );
01935         assert( rv < length );
01936         for( i=0; i<exp->value->width; i++ ) {
01937           (*info)[i+6] = (char*)malloc_safe( length );
01938           rv = snprintf( (*info)[i+6], length, "%s         %4u | %c    %c    %c    %c", spaces, i,
01939                          ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'),
01940                          ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'),
01941                          ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*'),
01942                          ((vector_get_eval_d( exp->value, i ) == 1) ? ' ' : '*') );
01943           assert( rv < length );
01944         }
01945 
01946       } else {
01947 
01948         length = 28 + strlen( spaces );
01949         (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s         LR | LR | LR | LR ", spaces );  assert( rv < length );
01950         (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        =00=|=01=|=10=|=11=", spaces );  assert( rv < length );
01951   
01952         length = 26 + strlen( spaces );
01953         (*info)[4] = (char*)malloc_safe( length );
01954         rv = snprintf( (*info)[4], length, "%s         %c    %c    %c    %c", spaces,
01955                        ((exp->suppl.part.eval_00 == 1) ? ' ' : '*'),
01956                        ((exp->suppl.part.eval_01 == 1) ? ' ' : '*'),
01957                        ((exp->suppl.part.eval_10 == 1) ? ' ' : '*'),
01958                        ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') );
01959         assert( rv < length );
01960 
01961       }
01962 
01963     }
01964 
01965   }
01966 
01967   PROFILE_END;
01968 
01969 }

void combination_unary char ***  info,
int *  info_size,
expression exp,
bool  show_excluded
[static]
 

Displays the missed unary combination(s) that keep the combination coverage for the specified expression from achieving 100% coverage.

Parameters:
info  Pointer to array of strings that will contain the coverage information for this expression
info_size  Pointer to integer containing number of elements in info array
exp  Pointer to expression to evaluate
show_excluded  Set to TRUE to output expression if it is excluded

01563   { PROFILE(COMBINATION_UNARY);
01564 
01565   int          hit = 0;                           /* Number of combinations hit for this expression */
01566   int          tot;                               /* Total number of coverage points possible */
01567   char         tmp[20];                           /* Temporary string used for sizing lines for numbers */
01568   unsigned int length;                            /* Length of the current line to allocate */
01569   char*        op = exp_op_info[exp->op].op_str;  /* Operations string */
01570   int          lines;                             /* Specifies the number of lines to allocate memory for */
01571   unsigned int rv;                                /* Return value from snprintf calls */
01572 
01573   assert( exp != NULL );
01574 
01575   /* Get hit information */
01576   if( report_bitwise && (exp->value->width > 1) ) {
01577     hit   = vector_get_eval_ab_count( exp->value );
01578     lines = exp->value->width + 2;
01579     tot   = (2 * exp->value->width);
01580   } else {
01581     lines = 1;
01582     tot   = 2;
01583     hit   = ESUPPL_WAS_FALSE( exp->suppl ) + ESUPPL_WAS_TRUE( exp->suppl );
01584   }
01585 
01586   if( (hit != tot) || (exp->suppl.part.excluded && show_excluded) ) {
01587 
01588     char         spaces[30];
01589     unsigned int eid_size;
01590 
01591     if( flag_output_exclusion_ids ) {
01592       eid_size = db_get_exclusion_id_size();
01593     }
01594 
01595     spaces[0] = '\0';
01596 
01597     assert( exp->ulid != -1 );
01598 
01599     /* Allocate memory for info array */
01600     *info_size = 4 + lines;
01601     *info      = (char**)malloc_safe( sizeof( char* ) * (*info_size) );
01602 
01603     /* Allocate lines and assign values */ 
01604     length = 26;
01605     rv = snprintf( tmp, 20, "%d", exp->ulid );  assert( rv < 20 );  length += strlen( tmp );
01606     rv = snprintf( tmp, 20, "%d", hit );        assert( rv < 20 );  length += strlen( tmp );
01607     rv = snprintf( tmp, 20, "%d", tot );        assert( rv < 20 );  length += strlen( tmp );
01608     if( flag_output_exclusion_ids ) {
01609       length += (eid_size - 1) + 4;
01610       gen_char_string( spaces, ' ', ((eid_size - 1) + 4) );
01611     }
01612     (*info)[0] = (char*)malloc_safe( length );
01613     if( flag_output_exclusion_ids ) {
01614       rv = snprintf( (*info)[0], length, "        (%s)  Expression %d   (%d/%d)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, tot );
01615     } else {
01616       rv = snprintf( (*info)[0], length, "        Expression %d   (%d/%d)", exp->ulid, hit, tot );
01617     }
01618     assert( rv < length );
01619 
01620     length = 25 + strlen( op ) + strlen( spaces );  (*info)[1] = (char*)malloc_safe( length );
01621     rv = snprintf( (*info)[1], length, "%s        ^^^^^^^^^^^^^ - %s", spaces, op );
01622     assert( rv < length );
01623 
01624     if( report_bitwise && (exp->value->width > 1) ) {
01625 
01626       char*        tmp;
01627       unsigned int i;
01628    
01629       length = 23 + strlen( spaces );
01630       (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s          Bit | E | E ", spaces );  assert( rv < length );
01631       (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        ======|=0=|=1=", spaces );  assert( rv < length );
01632       (*info)[5] = (char*)malloc_safe( length );  rv = snprintf( (*info)[5], length, "%s        ------|---|---", spaces );  assert( rv < length );
01633 
01634       length = 22 + strlen( spaces );
01635       (*info)[4] = (char*)malloc_safe( length );
01636       rv = snprintf( (*info)[4], length, "%s          All | %c   %c", spaces,
01637                      ((ESUPPL_WAS_FALSE( exp->suppl ) == 1) ? ' ' : '*'),
01638                      ((ESUPPL_WAS_TRUE( exp->suppl )  == 1) ? ' ' : '*') );
01639       assert( rv < length );
01640       for( i=0; i<exp->value->width; i++ ) {
01641         (*info)[i+6] = (char*)malloc_safe( length );
01642         rv = snprintf( (*info)[i+6], length, "%s         %4u | %c   %c", spaces, i,
01643                        ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'),
01644                        ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*') );
01645         assert( rv < length );
01646       }
01647 
01648     } else {
01649 
01650       length = 16 + strlen( spaces );
01651       (*info)[2] = (char*)malloc_safe( length );  rv = snprintf( (*info)[2], length, "%s         E | E ", spaces );
01652       (*info)[3] = (char*)malloc_safe( length );  rv = snprintf( (*info)[3], length, "%s        =0=|=1=", spaces );
01653 
01654       length = 15 + strlen( spaces );
01655       (*info)[4] = (char*)malloc_safe( length );
01656       rv = snprintf( (*info)[4], length, "%s         %c   %c", spaces,
01657                      ((ESUPPL_WAS_FALSE( exp->suppl ) == 1) ? ' ' : '*'),
01658                      ((ESUPPL_WAS_TRUE( exp->suppl )  == 1) ? ' ' : '*') );
01659       assert( rv < length );
01660 
01661     }
01662 
01663   }
01664 
01665   PROFILE_END;
01666 
01667 }

void combination_underline FILE *  ofile,
char **  code,
unsigned int  code_depth,
expression exp,
func_unit funit
[static]
 

Exceptions:
anonymous combination_underline_tree
Traverses through the expression tree that is on the same line as the parent, creating underline strings. An underline is created for each expression that does not have complete combination logic coverage. Each underline (children to parent creates an inverted tree) and contains a number for the specified expression.
Parameters:
ofile  Pointer output stream to display underlines to
code  Array of strings containing code to output
code_depth  Number of entries in code array
exp  Pointer to parent expression to create underline for
funit  Pointer to the functional unit containing the expression to underline

01497   { PROFILE(COMBINATION_UNDERLINE);
01498 
01499   char**       lines;      /* Pointer to a stack of lines */
01500   unsigned int depth;      /* Depth of underline stack */
01501   unsigned int size;       /* Width of stack in characters */
01502   unsigned int i;          /* Loop iterator */
01503   unsigned int j;          /* Loop iterator */
01504   char*        tmpstr;     /* Temporary string variable */
01505   unsigned int start = 0;  /* Starting index */
01506 
01507   combination_underline_tree( exp, 0, &lines, &depth, &size, exp->op, (code_depth == 1), funit );
01508 
01509   for( j=0; j<code_depth; j++ ) {
01510 
01511     assert( code[j] != NULL );
01512 
01513     if( j == 0 ) {
01514       fprintf( ofile, "        %7d:    %s\n", exp->line, code[j] );
01515     } else {
01516       fprintf( ofile, "                    %s\n", code[j] );
01517     }
01518 
01519     if( code_depth == 1 ) {
01520       for( i=0; i<depth; i++ ) {
01521         fprintf( ofile, "                    %s\n", lines[i] );
01522       }
01523     } else {
01524       for( i=0; i<depth; i++ ) {
01525         if( (tmpstr = combination_prep_line( lines[i], start, strlen( code[j] ) )) != NULL ) {
01526           fprintf( ofile, "                    %s\n", tmpstr );
01527           free_safe( tmpstr, (strlen( tmpstr ) + 1) );
01528         }
01529       }
01530     }
01531 
01532     start += strlen( code[j] );
01533 
01534     free_safe( code[j], (strlen( code[j] ) + 1) );
01535 
01536   }
01537 
01538   for( i=0; i<depth; i++ ) {
01539     free_safe( lines[i], (strlen( lines[i] ) + 1) );
01540   }
01541 
01542   if( depth > 0 ) {
01543     free_safe( lines, (sizeof( char* ) * depth) );
01544   }
01545 
01546   if( code_depth > 0 ) {
01547     free_safe( code, (sizeof( char* ) * code_depth) );
01548   }
01549 
01550   PROFILE_END;
01551 
01552 }

void combination_underline_tree expression exp,
unsigned int  curr_depth,
char ***  lines,
unsigned int *  depth,
unsigned int *  size,
exp_op_type  parent_op,
bool  center,
func_unit funit
[static]
 

Exceptions:
anonymous Throw Throw combination_underline_tree combination_underline_tree
Recursively parses specified expression tree, underlining and labeling each measurable expression.
Parameters:
exp  Pointer to expression to create underline for
curr_depth  Specifies current depth in expression tree
lines  Stack of lines for left child
depth  Pointer to top of left child stack
size  Pointer to character width of this node
parent_op  Expression operation of parent used for calculating parenthesis
center  Specifies if expression IDs should be centered in underlines or at beginning
funit  Pointer to current functional unit containing this expression

00891   { PROFILE(COMBINATION_UNDERLINE_TREE);
00892 
00893   char**       l_lines;         /* Pointer to left underline stack */
00894   char**       r_lines;         /* Pointer to right underline stack */
00895   unsigned int l_depth = 0;     /* Index to top of left stack */
00896   unsigned int r_depth = 0;     /* Index to top of right stack */
00897   unsigned int l_size;          /* Number of characters for left expression */
00898   unsigned int r_size;          /* Number of characters for right expression */
00899   char*        exp_sp;          /* Space to take place of missing expression(s) */
00900   char*        code_fmt;        /* Contains format string for rest of stack */
00901   char*        tmpstr;          /* Temporary string value */
00902   unsigned int comb_missed;     /* If set to 1, current combination was missed */
00903   char*        tmpname = NULL;  /* Temporary pointer to current signal name */
00904   char*        pname;           /* Printable version of signal/function/task name */
00905   func_unit*   tfunit;          /* Temporary pointer to found functional unit */
00906   int          ulid;            /* Underline ID to use */
00907   unsigned int rv;              /* Return value from snprintf calls */
00908   
00909   *depth      = 0;
00910   *size       = 0;
00911   l_lines     = NULL;
00912   r_lines     = NULL;
00913   comb_missed = 0;
00914   code_fmt    = (char*)malloc_safe( 300 );
00915 
00916   if( exp != NULL ) {
00917 
00918     if( (exp->op == EXP_OP_LAST) || (exp->op == EXP_OP_NB_CALL) ) {
00919 
00920       *size = 0;
00921 
00922     } else if( exp->op == EXP_OP_STATIC ) {
00923 
00924       unsigned int data_type = exp->value->suppl.part.data_type;
00925 
00926       if( data_type == VDATA_R64 ) {
00927 
00928         *size = strlen( exp->value->value.r64->str );
00929 
00930       } else if( data_type == VDATA_R32 ) {
00931 
00932         *size = strlen( exp->value->value.r32->str );
00933 
00934       } else if( ESUPPL_STATIC_BASE( exp->suppl ) == DECIMAL ) {
00935 
00936         rv = snprintf( code_fmt, 300, "%d", vector_to_int( exp->value ) );
00937         assert( rv < 300 );
00938         *size = strlen( code_fmt );
00939 
00940         /*
00941          If the size of this decimal value is only 1 and its parent is a NEGATE op,
00942          make it two so that we don't have problems with negates and the like later.
00943         */
00944         if( (*size == 1) && (exp->parent->expr->op == EXP_OP_NEGATE) ) {
00945           *size = 2;
00946         }
00947       
00948       } else {
00949 
00950         tmpstr = vector_to_string( exp->value, ESUPPL_STATIC_BASE( exp->suppl ), FALSE );
00951         *size  = strlen( tmpstr );
00952         free_safe( tmpstr, (strlen( tmpstr ) + 1) );
00953 
00954         /* Adjust for quotation marks */
00955         if( ESUPPL_STATIC_BASE( exp->suppl ) == QSTRING ) {
00956           *size += 2;
00957         }
00958 
00959       }
00960 
00961     } else if( exp->op == EXP_OP_SLIST ) {
00962 
00963       *size = 2;
00964       strcpy( code_fmt, "@*" );
00965 
00966     } else if( exp->op == EXP_OP_ALWAYS_COMB ) {
00967 
00968       *size = 11;
00969       strcpy( code_fmt, "always_comb" );
00970 
00971     } else if( exp->op == EXP_OP_ALWAYS_LATCH ) {
00972    
00973       *size = 12;
00974       strcpy( code_fmt, "always_latch" );
00975 
00976     } else if( exp->op == EXP_OP_STIME ) {
00977 
00978       *size = 5;
00979       strcpy( code_fmt, "$time" );
00980 
00981     } else if( (exp->op == EXP_OP_SRANDOM) && (exp->left == NULL) ) {
00982 
00983       *size = 7;
00984       strcpy( code_fmt, "$random" );
00985 
00986     } else if( (exp->op == EXP_OP_SURANDOM) && (exp->left == NULL) ) {
00987 
00988       *size = 8;
00989       strcpy( code_fmt, "$urandom" );
00990 
00991     } else {
00992 
00993       Try {
00994 
00995         if( (exp->op == EXP_OP_SIG) || (exp->op == EXP_OP_PARAM) ) {
00996 
00997           tmpname = scope_gen_printable( exp->name );
00998           *size   = strlen( tmpname );
00999           switch( *size ) {
01000             case 0 :  assert( *size > 0 );                     break;
01001             case 1 :  *size = 3;  strcpy( code_fmt, " %s " );  break;
01002             case 2 :  *size = 3;  strcpy( code_fmt, " %s" );   break;
01003             default:  strcpy( code_fmt, "%s" );                break;
01004           }
01005 
01006           free_safe( tmpname, (strlen( tmpname ) + 1) );
01007         
01008         } else {
01009 
01010           bool paren = (exp->suppl.part.parenthesis == 1);
01011 
01012           combination_underline_tree( exp->left,  combination_calc_depth( exp, curr_depth, TRUE ),  &l_lines, &l_depth, &l_size, exp->op, center, funit );
01013           combination_underline_tree( exp->right, combination_calc_depth( exp, curr_depth, FALSE ), &r_lines, &r_depth, &r_size, exp->op, center, funit );
01014 
01015           switch( exp->op ) {
01016             case EXP_OP_XOR        :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01017             case EXP_OP_XOR_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01018             case EXP_OP_MULTIPLY   :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01019             case EXP_OP_MLT_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01020             case EXP_OP_DIVIDE     :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01021             case EXP_OP_DIV_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01022             case EXP_OP_MOD        :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01023             case EXP_OP_MOD_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01024             case EXP_OP_ADD        :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01025             case EXP_OP_ADD_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01026             case EXP_OP_SUBTRACT   :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01027             case EXP_OP_SUB_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01028             case EXP_OP_EXPONENT   :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01029             case EXP_OP_AND        :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01030             case EXP_OP_AND_A      :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01031             case EXP_OP_OR         :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01032             case EXP_OP_OR_A       :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01033             case EXP_OP_NAND       :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01034             case EXP_OP_NOR        :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01035             case EXP_OP_NXOR       :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01036             case EXP_OP_LT         :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01037             case EXP_OP_GT         :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01038             case EXP_OP_LSHIFT     :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01039             case EXP_OP_LS_A       :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01040             case EXP_OP_ALSHIFT    :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01041             case EXP_OP_ALS_A      :  *size = l_size + r_size + 6;  combination_parenthesize( paren, "%s      %s", &code_fmt, size );  break;
01042             case EXP_OP_RSHIFT     :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01043             case EXP_OP_RS_A       :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01044             case EXP_OP_ARSHIFT    :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01045             case EXP_OP_ARS_A      :  *size = l_size + r_size + 6;  combination_parenthesize( paren, "%s      %s", &code_fmt, size );  break;
01046             case EXP_OP_EQ         :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01047             case EXP_OP_CEQ        :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01048             case EXP_OP_LE         :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01049             case EXP_OP_GE         :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01050             case EXP_OP_NE         :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01051             case EXP_OP_CNE        :  *size = l_size + r_size + 5;  combination_parenthesize( paren, "%s     %s",  &code_fmt, size );  break;
01052             case EXP_OP_LOR        :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01053             case EXP_OP_LAND       :  *size = l_size + r_size + 4;  combination_parenthesize( paren, "%s    %s",   &code_fmt, size );  break;
01054             case EXP_OP_COND       :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01055             case EXP_OP_COND_SEL   :  *size = l_size + r_size + 3;  combination_parenthesize( paren, "%s   %s",    &code_fmt, size );  break;
01056             case EXP_OP_UINV       :  *size = l_size + r_size + 1;  combination_parenthesize( paren, " %s",        &code_fmt, size );  break;
01057             case EXP_OP_UAND       :  *size = l_size + r_size + 1;  combination_parenthesize( paren, " %s",        &code_fmt, size );  break;
01058             case EXP_OP_UNOT       :  *size = l_size + r_size + 1;  combination_parenthesize( paren, " %s",        &code_fmt, size );  break;
01059             case EXP_OP_UOR        :  *size = l_size + r_size + 1;  combination_parenthesize( paren, " %s",        &code_fmt, size );  break;
01060             case EXP_OP_UXOR       :  *size = l_size + r_size + 1;  combination_parenthesize( paren, " %s",        &code_fmt, size );  break;
01061             case EXP_OP_UNAND      :  *size = l_size + r_size + 2;  combination_parenthesize( paren, "  %s",       &code_fmt, size );  break;
01062             case EXP_OP_UNOR       :  *size = l_size + r_size + 2;  combination_parenthesize( paren, "  %s",       &code_fmt, size );  break;
01063             case EXP_OP_UNXOR      :  *size = l_size + r_size + 2;  combination_parenthesize( paren, "  %s",       &code_fmt, size );  break;
01064             case EXP_OP_PARAM_SBIT :
01065             case EXP_OP_SBIT_SEL   :  
01066               if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) &&
01067                   (exp->parent->expr->op == EXP_OP_DIM) &&
01068                   (exp->parent->expr->right == exp) ) {
01069                 *size = l_size + r_size + 2;
01070                 code_fmt[0] = '\0';
01071               } else {
01072                 unsigned int i;
01073                 tmpname = scope_gen_printable( exp->name );
01074                 *size = l_size + r_size + strlen( tmpname ) + 2;
01075                 for( i=0; i<strlen( tmpname ); i++ ) {
01076                   code_fmt[i] = ' ';
01077                 }
01078                 code_fmt[i] = '\0';
01079               }
01080               strcat( code_fmt, " %s " );
01081               free_safe( tmpname, (strlen( tmpname ) + 1) );
01082               break;
01083             case EXP_OP_PARAM_MBIT :
01084             case EXP_OP_MBIT_SEL   :  
01085               if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) &&
01086                   (exp->parent->expr->op == EXP_OP_DIM) &&
01087                   (exp->parent->expr->right == exp) ) {
01088                 *size = l_size + r_size + 3;
01089                 code_fmt[0] = '\0';
01090               } else {
01091                 unsigned int i;
01092                 tmpname = scope_gen_printable( exp->name );
01093                 *size = l_size + r_size + strlen( tmpname ) + 3;  
01094                 for( i=0; i<strlen( tmpname ); i++ ) {
01095                   code_fmt[i] = ' ';
01096                 }
01097                 code_fmt[i] = '\0';
01098               }
01099               strcat( code_fmt, " %s %s " );
01100               free_safe( tmpname, (strlen( tmpname ) + 1) );
01101               break;
01102             case EXP_OP_PARAM_MBIT_POS :
01103             case EXP_OP_PARAM_MBIT_NEG :
01104             case EXP_OP_MBIT_POS       :
01105             case EXP_OP_MBIT_NEG       :
01106               if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) &&
01107                   (exp->parent->expr->op == EXP_OP_DIM) &&
01108                   (exp->parent->expr->right == exp) ) {
01109                 *size = l_size + r_size + 4;
01110                 code_fmt[0] = '\0';
01111               } else {
01112                 unsigned int i;
01113                 tmpname = scope_gen_printable( exp->name );
01114                 *size = l_size + r_size + strlen( tmpname ) + 4;
01115                 for( i=0; i<strlen( tmpname ); i++ ) {
01116                   code_fmt[i] = ' ';
01117                 }
01118                 code_fmt[i] = '\0';
01119               }
01120               strcat( code_fmt, " %s  %s " );
01121               free_safe( tmpname, (strlen( tmpname ) + 1) );
01122               break;
01123             case EXP_OP_TRIGGER  :
01124               {
01125                 unsigned int i;
01126                 tmpname = scope_gen_printable( exp->name );
01127                 *size = l_size + r_size + strlen( tmpname ) + 2;
01128                 for( i=0; i<strlen( tmpname ) + 2; i++ ) {
01129                   code_fmt[i] = ' ';
01130                 }
01131                 code_fmt[i] = '\0';
01132                 free_safe( tmpname, (strlen( tmpname ) + 1) );
01133               }
01134               break;
01135             case EXP_OP_EXPAND   :  *size = l_size + r_size + 4;  strcpy( code_fmt, " %s %s  "         );  break;
01136             case EXP_OP_CONCAT   :  *size = l_size + r_size + 2;  strcpy( code_fmt, " %s "             );  break;
01137             case EXP_OP_PLIST    :
01138             case EXP_OP_LIST     :  *size = l_size + r_size + 2;  strcpy( code_fmt, "%s  %s"           );  break;
01139             case EXP_OP_PEDGE    :
01140               if( (ESUPPL_IS_ROOT( exp->suppl ) == 1)       ||
01141                   (exp->parent->expr->op == EXP_OP_RPT_DLY) ||
01142                   (exp->parent->expr->op == EXP_OP_DLY_OP) ) {
01143                 *size = l_size + r_size + 11;  strcpy( code_fmt, "          %s " );
01144               } else {
01145                 *size = l_size + r_size + 8;   strcpy( code_fmt, "        %s" );
01146               }
01147               break;
01148             case EXP_OP_NEDGE    :
01149               if( (ESUPPL_IS_ROOT( exp->suppl ) == 1)       ||
01150                   (exp->parent->expr->op == EXP_OP_RPT_DLY) ||
01151                   (exp->parent->expr->op == EXP_OP_DLY_OP) ) {
01152                 *size = l_size + r_size + 11;  strcpy( code_fmt, "          %s " );
01153               } else {
01154                 *size = l_size + r_size + 8;   strcpy( code_fmt, "        %s" );
01155               }
01156               break;
01157             case EXP_OP_AEDGE    :
01158               if( (ESUPPL_IS_ROOT( exp->suppl ) == 1)       ||
01159                   (exp->parent->expr->op == EXP_OP_RPT_DLY) ||
01160                   (exp->parent->expr->op == EXP_OP_DLY_OP) ) {
01161                 *size = l_size + r_size + 3;  strcpy( code_fmt, "  %s " );
01162               } else {
01163                 *size = l_size + r_size + 0;  strcpy( code_fmt, "%s" );
01164               }
01165               break;
01166             case EXP_OP_EOR      :
01167               if( (ESUPPL_IS_ROOT( exp->suppl ) == 1)       ||
01168                   (exp->parent->expr->op == EXP_OP_RPT_DLY) ||
01169                   (exp->parent->expr->op == EXP_OP_DLY_OP) ) {
01170                 *size = l_size + r_size + 7;  strcpy( code_fmt, "  %s    %s " );
01171               } else {
01172                 *size = l_size + r_size + 4;  strcpy( code_fmt, "%s    %s" );
01173               }
01174               break;
01175             case EXP_OP_CASE     :  *size = l_size + r_size + 11; strcpy( code_fmt, "      %s   %s  "  );  break;
01176             case EXP_OP_CASEX    :  *size = l_size + r_size + 12; strcpy( code_fmt, "       %s   %s  " );  break;
01177             case EXP_OP_CASEZ    :  *size = l_size + r_size + 12; strcpy( code_fmt, "       %s   %s  " );  break;
01178             case EXP_OP_DELAY    :  *size = r_size + 3;  strcpy( code_fmt, "  %s " );             break;
01179             case EXP_OP_ASSIGN   :  *size = l_size + r_size + 10; strcpy( code_fmt, "       %s   %s" );    break;
01180             case EXP_OP_DASSIGN  :
01181             case EXP_OP_DLY_ASSIGN :
01182             case EXP_OP_BASSIGN  :  *size = l_size + r_size + 3;  strcpy( code_fmt, "%s   %s" );           break;
01183             case EXP_OP_NASSIGN  :  *size = l_size + r_size + 4;  strcpy( code_fmt, "%s    %s" );          break;
01184             case EXP_OP_SASSIGN  :
01185             case EXP_OP_PASSIGN  :  *size = r_size;               strcpy( code_fmt, "%s" );                break;
01186             case EXP_OP_IF       :  *size = r_size + 6;           strcpy( code_fmt, "    %s  " );          break;
01187             case EXP_OP_REPEAT   :  *size = r_size + 10;          strcpy( code_fmt, "        %s  " );      break;
01188             case EXP_OP_WHILE    :  *size = r_size + 9;           strcpy( code_fmt, "       %s  " );       break;
01189             case EXP_OP_WAIT     :  *size = r_size + 8;           strcpy( code_fmt, "      %s  " );        break;
01190             case EXP_OP_DLY_OP   :
01191             case EXP_OP_RPT_DLY  :  *size = l_size + r_size + 1;  strcpy( code_fmt, "%s %s" );             break;
01192             case EXP_OP_TASK_CALL :
01193             case EXP_OP_FUNC_CALL :
01194               {
01195                 unsigned int i;
01196                 tfunit = exp->elem.funit;
01197                 tmpname = strdup_safe( tfunit->name );
01198                 scope_extract_back( tfunit->name, tmpname, user_msg );
01199                 pname = scope_gen_printable( tmpname );
01200                 *size = l_size + r_size + strlen( pname ) + 4;
01201                 for( i=0; i<strlen( pname ); i++ ) {
01202                   code_fmt[i] = ' ';
01203                 }
01204                 code_fmt[i] = '\0';
01205                 strcat( code_fmt, "  %s  " );
01206                 free_safe( tmpname, (strlen( tfunit->name ) + 1) );
01207                 free_safe( pname, (strlen( pname ) + 1) );
01208               }
01209               break;
01210             case EXP_OP_NEGATE       :  *size = l_size + r_size + 1;  strcpy( code_fmt, " %s"                    );  break;
01211             case EXP_OP_DIM          :  *size = l_size + r_size;      strcpy( code_fmt, "%s%s"                   );  break;
01212             case EXP_OP_IINC         :
01213             case EXP_OP_IDEC         :  *size = l_size + 2;           strcpy( code_fmt, "  %s"                   );  break;
01214             case EXP_OP_PINC         :
01215             case EXP_OP_PDEC         :  *size = l_size + 2;           strcpy( code_fmt, "%s  "                   );  break;
01216             case EXP_OP_SSIGNED      :  *size = l_size + 11;          strcpy( code_fmt, "         %s  "          );  break;
01217             case EXP_OP_SUNSIGNED    :  *size = l_size + 13;          strcpy( code_fmt, "           %s  "        );  break;
01218             case EXP_OP_SRANDOM      :  *size = l_size + 11;          strcpy( code_fmt, "         %s  "          );  break;
01219             case EXP_OP_SURANDOM     :  *size = l_size + 12;          strcpy( code_fmt, "          %s  "         );  break;
01220             case EXP_OP_SURAND_RANGE :  *size = l_size + 18;          strcpy( code_fmt, "                %s  "   );  break;
01221             case EXP_OP_SSRANDOM     :  *size = l_size + 12;          strcpy( code_fmt, "          %s  "         );  break;
01222             case EXP_OP_SR2B         :
01223             case EXP_OP_SB2R         :  *size = l_size + 15;          strcpy( code_fmt, "             %s  "      );  break;
01224             case EXP_OP_SI2R         :
01225             case EXP_OP_SR2I         :  *size = l_size + 9;           strcpy( code_fmt, "       %s  "            );  break;
01226             case EXP_OP_SSR2B        :
01227             case EXP_OP_SB2SR        :  *size = l_size + 20;          strcpy( code_fmt, "                  %s  " );  break;
01228             case EXP_OP_STESTARGS    :  *size = l_size + 18;          strcpy( code_fmt, "                %s  "   );  break;
01229             case EXP_OP_SVALARGS     :  *size = l_size + 19;          strcpy( code_fmt, "                 %s  "  );  break;
01230             default              :
01231               rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error:  Unknown expression type in combination_underline_tree (%d)", exp->op );
01232               assert( rv < USER_MSG_LENGTH );
01233               print_output( user_msg, FATAL, __FILE__, __LINE__ );
01234               Throw 0;
01235               /*@-unreachable@*/
01236               break;
01237               /*@=unreachable@*/
01238   
01239           }
01240   
01241         }
01242 
01243         /* Calculate ulid */
01244         ulid = exp->ulid;
01245 
01246         comb_missed = (((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) ||
01247                         (report_comb_depth == REPORT_VERBOSE)) ? ((ulid != -1) ? 1 : 0) : 0;
01248 
01249         if( l_depth > r_depth ) {
01250           *depth = l_depth + comb_missed;
01251         } else {
01252           *depth = r_depth + comb_missed;
01253         }
01254       
01255         if( *depth > 0 ) {
01256 
01257           unsigned int i;
01258                 
01259           /* Allocate all memory for the stack */
01260           *lines = (char**)malloc_safe( sizeof( char* ) * (*depth) );
01261 
01262           /* Create underline or space */
01263           if( comb_missed == 1 ) {
01264 
01265             /* Allocate memory for this underline */
01266             (*lines)[(*depth)-1] = (char*)malloc_safe( *size + 1 );
01267 
01268             if( center ) {
01269               combination_draw_centered_line( (*lines)[(*depth)-1], *size, ulid, TRUE, TRUE );
01270             } else {
01271               combination_draw_line( (*lines)[(*depth)-1], *size, ulid );
01272             }
01273             /* printf( "Drawing line (%s), size: %d, depth: %d\n", (*lines)[(*depth)-1], *size, (*depth) ); */
01274           }
01275 
01276           /* Combine the left and right line stacks */
01277           for( i=0; i<(*depth - comb_missed); i++ ) {
01278 
01279             (*lines)[i] = (char*)malloc_safe( *size + 1 );
01280 
01281             if( (i < l_depth) && (i < r_depth) ) {
01282             
01283               /* Merge left and right lines */
01284               rv = snprintf( (*lines)[i], (*size + 1), code_fmt, l_lines[i], r_lines[i] );
01285               assert( rv < (*size + 1) );
01286             
01287               free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) );
01288               free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) );
01289 
01290             } else if( i < l_depth ) {
01291             
01292               /* Create spaces for right side */
01293               exp_sp = (char*)malloc_safe( r_size + 1 );
01294               gen_char_string( exp_sp, ' ', r_size );
01295 
01296               /* Merge left side only */
01297               rv = snprintf( (*lines)[i], (*size + 1), code_fmt, l_lines[i], exp_sp );
01298               assert( rv < (*size + 1) );
01299             
01300               free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) );
01301               free_safe( exp_sp, (r_size + 1) );
01302 
01303             } else if( i < r_depth ) {
01304 
01305               if( l_size == 0 ) { 
01306 
01307                 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, r_lines[i] );
01308                 assert( rv < (*size + 1) );
01309 
01310               } else {
01311 
01312                 /* Create spaces for left side */
01313                 exp_sp = (char*)malloc_safe( l_size + 1 );
01314                 gen_char_string( exp_sp, ' ', l_size );
01315 
01316                 /* Merge right side only */
01317                 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, exp_sp, r_lines[i] );
01318                 assert( rv < (*size + 1) );
01319               
01320                 free_safe( exp_sp, (l_size + 1) );
01321           
01322               }
01323   
01324               free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) );
01325    
01326             } else {
01327 
01328               print_output( "Internal error:  Reached entry without a left or right underline", FATAL, __FILE__, __LINE__ );
01329               Throw 0;
01330 
01331             }
01332 
01333           }
01334 
01335           /* Free left child stack */
01336           if( l_depth > 0 ) {
01337             free_safe( l_lines, (sizeof( char* ) * l_depth) );
01338           }
01339 
01340           /* Free right child stack */
01341           if( r_depth > 0 ) {
01342             free_safe( r_lines, (sizeof( char* ) * r_depth) );
01343           }
01344 
01345         }
01346 
01347       } Catch_anonymous {
01348         unsigned int i;
01349         for( i=0; i<(*depth - comb_missed); i++ ) {
01350           free_safe( (*lines)[i], (strlen( (*lines)[i] ) + 1) );
01351         }
01352         free_safe( *lines, (sizeof( char* ) * (*depth - comb_missed)) );
01353         *lines = NULL;
01354         *depth = 0;
01355         for( i=0; i<l_depth; i++ ) {
01356           free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) );
01357         }
01358         free_safe( l_lines, (sizeof( char* ) * l_depth) );
01359         for( i=0; i<r_depth; i++ ) {
01360           free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) );
01361         }
01362         free_safe( r_lines, (sizeof( char* ) * r_depth) );
01363         Throw 0;
01364       }
01365 
01366     }
01367 
01368   }
01369 
01370   /* Deallocate the code_fmt string */
01371   free_safe( code_fmt, 300 );
01372 
01373   PROFILE_END;
01374     
01375 }


Variable Documentation

bool allow_multi_expr = TRUE
 

Controls whether multi-expressions are used or not.

unsigned int curr_db
 

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

db** db_list
 

Array of database pointers storing all currently loaded databases.

const exp_info exp_op_info[EXP_OP_NUM]
 

Array containing static information about expression operation types. NOTE: This structure MUST be updated if a new expression is added! The third argument is an initialization to the exp_info_s structure.

bool flag_output_exclusion_ids
 

Outputs the exclusion ID for an output coverage point. The exclusion ID can be used by the exclude command for excluding/including coverage points.

isuppl info_suppl
 

Informational line for the CDD file.

int line_width
 

Specifies the number of characters wide that an expression will allowed to be output for if the flag_use_line_width value is set to TRUE.

bool report_bitwise
 

If set to a boolean value of TRUE, displays all vector combinational logic on a bitwise basis.

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.

bool report_covered
 

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.

bool report_exclusions
 

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.

bool report_instance
 

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.

char user_msg[USER_MSG_LENGTH]
 

Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.


Generated on Wed Jun 17 22:19:20 2009 for Covered by doxygen 1.3.4