#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include "codegen.h"
#include "comb.h"
#include "defines.h"
#include "db.h"
#include "exclude.h"
#include "expr.h"
#include "func_unit.h"
#include "link.h"
#include "obfuscate.h"
#include "ovl.h"
#include "util.h"
#include "vector.h"
Functions | |
static int | combination_calc_depth (expression *exp, unsigned int curr_depth, bool left) |
static bool | combination_does_multi_exp_need_ul (expression *exp) |
static void | combination_multi_expr_calc (expression *exp, int *ulid, bool ul, bool excluded, unsigned int *hit, unsigned int *excludes, unsigned int *total) |
static 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. | |
static 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. | |
static bool | combination_display_instance_summary (FILE *ofile, char *name, int hits, int total) |
static bool | combination_instance_summary (FILE *ofile, funit_inst *root, char *parent, int *hits, int *total) |
static bool | combination_display_funit_summary (FILE *ofile, const char *name, const char *fname, int hits, int total) |
static bool | combination_funit_summary (FILE *ofile, funit_link *head, int *hits, int *total) |
static void | combination_draw_line (char *line, int size, int exp_id) |
static void | combination_draw_centered_line (char *line, int size, int exp_id, bool left_bar, bool right_bar) |
static void | combination_parenthesize (bool parenthesis, const char *pre_code_format, char **new_code_format, unsigned int *code_format_size) |
static 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 char * | combination_prep_line (char *line, int start, int len) |
static void | combination_underline (FILE *ofile, char **code, unsigned int code_depth, expression *exp, func_unit *funit) |
static void | combination_unary (char ***info, int *info_size, expression *exp, bool show_excluded) |
static void | combination_event (char ***info, int *info_size, expression *exp, bool show_excluded) |
static void | combination_two_vars (char ***info, int *info_size, expression *exp, bool show_excluded) |
static void | combination_multi_var_exprs (char **line1, char **line2, char **line3, expression *exp) |
static int | combination_multi_expr_output_length (char *line1) |
static void | combination_multi_expr_output (char **info, char *line1, char *line2, char *line3) |
static void | combination_multi_vars (char ***info, int *info_size, expression *exp, bool show_excluded) |
static void | combination_get_missed_expr (char ***info, int *info_size, expression *exp, unsigned int curr_depth, bool show_excluded) |
static void | combination_list_missed (FILE *ofile, expression *exp, unsigned int curr_depth, func_unit *funit, bool show_exclusions) |
static void | combination_output_expr (expression *expr, unsigned int curr_depth, int *any_missed, int *any_measurable, int *any_excluded, int *all_excluded) |
static void | combination_display_verbose (FILE *ofile, func_unit *funit, rpt_type rtype) |
static void | combination_instance_verbose (FILE *ofile, funit_inst *root, char *parent) |
static 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. | |
static 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 |
static int combination_calc_depth | ( | expression * | exp, | |
unsigned int | curr_depth, | |||
bool | left | |||
) | [static] |
Based on the current point in the expression tree, calculates the left or right child's curr_depth value.
exp | Pointer to current expression | |
curr_depth | Current depth in expression tree | |
left | TRUE if evaluating for left child |
References expression_s::left, expression_s::op, PROFILE, PROFILE_END, report_comb_depth, REPORT_DETAILED, REPORT_VERBOSE, and expression_s::right.
Referenced by combination_get_tree_stats(), combination_list_missed(), combination_output_expr(), and combination_underline_tree().
00111 { PROFILE(COMBINATION_CALC_DEPTH); 00112 00113 int our_depth; /* Return value for this function */ 00114 00115 if( ((report_comb_depth == REPORT_DETAILED) && ((curr_depth + 1) <= report_comb_depth)) || 00116 (report_comb_depth == REPORT_VERBOSE) ) { 00117 00118 if( left ) { 00119 00120 if( (exp->left != NULL) && (exp->op == exp->left->op) ) { 00121 our_depth = curr_depth; 00122 } else { 00123 our_depth = curr_depth + 1; 00124 } 00125 00126 } else { 00127 00128 if( (exp->right != NULL) && (exp->op == exp->right->op) ) { 00129 our_depth = curr_depth; 00130 } else { 00131 our_depth = curr_depth + 1; 00132 } 00133 00134 } 00135 00136 } else { 00137 00138 our_depth = curr_depth + 1; 00139 00140 } 00141 00142 PROFILE_END; 00143 00144 return( our_depth ); 00145 00146 }
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.
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 |
References esuppl_u::comb_cntd, combination_output_expr(), combination_reset_counted_exprs(), statement_s::exp, FALSE, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), expression_s::line, esuppl_u::part, PROFILE, PROFILE_END, realloc_safe, expression_s::suppl, and TRUE.
02792 { PROFILE(COMBINATION_COLLECT); 02793 02794 func_iter fi; /* Functional unit iterator */ 02795 statement* stmt; /* Pointer to current statement */ 02796 02797 /* Reset combination counted bits */ 02798 combination_reset_counted_exprs( funit ); 02799 02800 /* Create an array that will hold the number of uncovered combinations */ 02801 *exp_cnt = 0; 02802 *exprs = NULL; 02803 *excludes = NULL; 02804 02805 func_iter_init( &fi, funit, TRUE, FALSE ); 02806 02807 stmt = func_iter_get_next_statement( &fi ); 02808 while( stmt != NULL ) { 02809 02810 int any_missed = 0; 02811 int any_measurable = 0; 02812 int any_excluded = 0; 02813 int all_excluded = 0; 02814 02815 combination_output_expr( stmt->exp, 0, &any_missed, &any_measurable, &any_excluded, &all_excluded ); 02816 02817 /* Check for uncovered statements */ 02818 if( ((cov == 0) && (any_missed == 1)) || 02819 ((cov == 1) && (any_missed == 0) && (any_measurable == 1)) ) { 02820 if( stmt->exp->line != 0 ) { 02821 *exprs = (expression**)realloc_safe( *exprs, (sizeof( expression* ) * (*exp_cnt)), (sizeof( expression* ) * (*exp_cnt + 1)) ); 02822 *excludes = (int*)realloc_safe( *excludes, (sizeof( int* ) * (*exp_cnt)), (sizeof( int* ) * (*exp_cnt + 1)) ); 02823 02824 (*exprs)[(*exp_cnt)] = stmt->exp; 02825 (*excludes)[(*exp_cnt)] = all_excluded ? 1 : 0; 02826 (*exp_cnt)++; 02827 } 02828 stmt->exp->suppl.part.comb_cntd = 0; 02829 } 02830 02831 stmt = func_iter_get_next_statement( &fi ); 02832 02833 } 02834 02835 func_iter_dealloc( &fi ); 02836 02837 PROFILE_END; 02838 02839 }
static bool combination_display_funit_summary | ( | FILE * | ofile, | |
const char * | name, | |||
const char * | fname, | |||
int | hits, | |||
int | total | |||
) | [static] |
Outputs the summary combinational logic information for the specified functional unit to the given output stream.
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 |
References calc_miss_percent(), PROFILE, and PROFILE_END.
Referenced by combination_funit_summary(), and combination_report().
00701 { PROFILE(COMBINATION_DISPLAY_FUNIT_SUMMARY); 00702 00703 float percent; /* Percentage of lines hit */ 00704 int miss; /* Number of lines missed */ 00705 00706 calc_miss_percent( hits, total, &miss, &percent ); 00707 00708 fprintf( ofile, " %-30.30s %-30.30s %4d/%4d/%4d %3.0f%%\n", 00709 name, fname, hits, miss, total, percent ); 00710 00711 PROFILE_END; 00712 00713 return( miss > 0 ); 00714 00715 }
static 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.
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 |
References calc_miss_percent(), PROFILE, and PROFILE_END.
Referenced by combination_instance_summary(), and combination_report().
00605 { PROFILE(COMBINATION_DISPLAY_INSTANCE_SUMMARY); 00606 00607 float percent; /* Percentage of lines hit */ 00608 int miss; /* Number of lines missed */ 00609 00610 calc_miss_percent( hits, total, &miss, &percent ); 00611 00612 fprintf( ofile, " %-63.63s %4d/%4d/%4d %3.0f%%\n", 00613 name, hits, miss, total, percent ); 00614 00615 PROFILE_END; 00616 00617 return( miss > 0 ); 00618 00619 }
static void combination_display_verbose | ( | FILE * | ofile, | |
func_unit * | funit, | |||
rpt_type | rtype | |||
) | [static] |
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.
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 |
References codegen_gen_expr(), esuppl_u::comb_cntd, combination_list_missed(), combination_output_expr(), combination_underline(), statement_s::exp, FALSE, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), expression_s::op, esuppl_u::part, PROFILE, PROFILE_END, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, expression_s::suppl, and TRUE.
Referenced by combination_funit_verbose(), and combination_instance_verbose().
02587 { PROFILE(COMBINATION_DISPLAY_VERBOSE); 02588 02589 func_iter fi; /* Functional unit iterator */ 02590 statement* stmt; /* Pointer to current statement */ 02591 char** code; /* Code string from code generator */ 02592 unsigned int code_depth; /* Depth of code array */ 02593 02594 switch( rtype ) { 02595 case RPT_TYPE_HIT : fprintf( ofile, " Hit Combinations\n\n" ); break; 02596 case RPT_TYPE_MISS : fprintf( ofile, " Missed Combinations (* = missed value)\n\n" ); break; 02597 case RPT_TYPE_EXCL : fprintf( ofile, " Excluded Combinations\n\n" ); break; 02598 } 02599 02600 /* Initialize functional unit iterator */ 02601 func_iter_init( &fi, funit, TRUE, FALSE ); 02602 02603 /* Display missed combinations */ 02604 stmt = func_iter_get_next_statement( &fi ); 02605 while( stmt != NULL ) { 02606 02607 int any_missed = 0; 02608 int any_measurable = 0; 02609 int any_excluded = 0; 02610 int all_excluded = 0; 02611 02612 combination_output_expr( stmt->exp, 0, &any_missed, &any_measurable, &any_excluded, &all_excluded ); 02613 02614 if( ((rtype == RPT_TYPE_MISS) && (any_missed == 1) && (all_excluded == 0) && (any_measurable == 1)) || 02615 ((rtype == RPT_TYPE_HIT) && (any_missed == 0) && (any_measurable == 1)) || 02616 ((rtype == RPT_TYPE_EXCL) && (any_excluded == 1)) ) { 02617 02618 stmt->exp->suppl.part.comb_cntd = 0; 02619 02620 fprintf( ofile, " =========================================================================================================\n" ); 02621 fprintf( ofile, " Line # Expression\n" ); 02622 fprintf( ofile, " =========================================================================================================\n" ); 02623 02624 /* Generate line of code that missed combinational coverage */ 02625 codegen_gen_expr( stmt->exp, stmt->exp->op, &code, &code_depth, funit ); 02626 02627 /* Output underlining feature for missed expressions */ 02628 combination_underline( ofile, code, code_depth, stmt->exp, funit ); 02629 fprintf( ofile, "\n" ); 02630 02631 /* Output logical combinations that missed complete coverage */ 02632 combination_list_missed( ofile, stmt->exp, 0, funit, (rtype == RPT_TYPE_EXCL) ); 02633 02634 } 02635 02636 stmt = func_iter_get_next_statement( &fi ); 02637 02638 } 02639 02640 /* Deallocate functional unit iterator */ 02641 func_iter_dealloc( &fi ); 02642 02643 PROFILE_END; 02644 02645 }
static bool combination_does_multi_exp_need_ul | ( | expression * | exp | ) | [static] |
exp | Pointer to expression to check for multi-expression underlines |
References ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_11, EXP_OP_AND, EXP_OP_LAND, FALSE, expression_s::left, expression_s::op, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, and expression_s::suppl.
Referenced by combination_multi_expr_calc().
00153 { PROFILE(COMBINATION_DOES_MULTI_EXP_NEED_UL); 00154 00155 bool ul = FALSE; /* Return value for this function */ 00156 bool and_op; /* Specifies if current expression is an AND or LAND operation */ 00157 00158 if( exp != NULL ) { 00159 00160 /* Figure out if this is an AND/LAND operation */ 00161 and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND); 00162 00163 /* Decide if our expression requires that this sequence gets underlined */ 00164 if( and_op ) { 00165 ul = (exp->suppl.part.eval_11 == 0) || (ESUPPL_WAS_FALSE( exp->left->suppl ) == 0) || (ESUPPL_WAS_FALSE( exp->right->suppl ) == 0); 00166 } else { 00167 ul = (exp->suppl.part.eval_00 == 0) || (ESUPPL_WAS_TRUE( exp->left->suppl ) == 0) || (ESUPPL_WAS_TRUE( exp->right->suppl ) == 0); 00168 } 00169 00170 /* If we did not require underlining, check our left child */ 00171 if( !ul && ((exp->left == NULL) || (exp->op == exp->left->op)) ) { 00172 ul = combination_does_multi_exp_need_ul( exp->left ); 00173 } 00174 00175 /* If we still have not found a reason to underline, check our right child */ 00176 if( !ul && ((exp->right == NULL) || (exp->op == exp->right->op)) ) { 00177 ul = combination_does_multi_exp_need_ul( exp->right ); 00178 } 00179 00180 } 00181 00182 PROFILE_END; 00183 00184 return( ul ); 00185 00186 }
static 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.
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 |
References PROFILE, and PROFILE_END.
Referenced by combination_prep_line(), and combination_underline_tree().
00808 { PROFILE(COMBINATION_DRAW_CENTERED_LINE); 00809 00810 char str_exp_id[12]; /* String containing value of exp_id */ 00811 int exp_id_size; /* Number of characters exp_id is in length */ 00812 int i; /* Loop iterator */ 00813 unsigned int rv; /* Return value from snprintf call */ 00814 00815 /* Calculate size of expression ID */ 00816 rv = snprintf( str_exp_id, 12, "%d", exp_id ); 00817 assert( rv < 12 ); 00818 exp_id_size = strlen( str_exp_id ); 00819 00820 if( left_bar ) { 00821 line[0] = '|'; 00822 } else { 00823 line[0] = '-'; 00824 } 00825 00826 for( i=1; i<((size - exp_id_size) / 2); i++ ) { 00827 line[i] = '-'; 00828 } 00829 00830 line[i] = '\0'; 00831 strcat( line, str_exp_id ); 00832 00833 for( i=(i + exp_id_size); i<(size - 1); i++ ) { 00834 line[i] = '-'; 00835 } 00836 00837 if( right_bar ) { 00838 line[i] = '|'; 00839 } else { 00840 line[i] = '-'; 00841 } 00842 line[i+1] = '\0'; 00843 00844 PROFILE_END; 00845 00846 }
static 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.
line | Pointer to line to create line onto | |
size | Number of characters long line is | |
exp_id | ID to place in underline |
References PROFILE, and PROFILE_END.
Referenced by combination_underline_tree().
00771 { PROFILE(COMBINATION_DRAW_LINE); 00772 00773 char str_exp_id[12]; /* String containing value of exp_id */ 00774 int exp_id_size; /* Number of characters exp_id is in length */ 00775 int i; /* Loop iterator */ 00776 unsigned int rv; /* Return value from calls to snprintf */ 00777 00778 /* Calculate size of expression ID */ 00779 rv = snprintf( str_exp_id, 12, "%d", exp_id ); 00780 assert( rv < 12 ); 00781 exp_id_size = strlen( str_exp_id ); 00782 00783 line[0] = '|'; 00784 line[1] = '\0'; 00785 strcat( line, str_exp_id ); 00786 00787 for( i=(exp_id_size + 1); i<(size - 1); i++ ) { 00788 line[i] = '-'; 00789 } 00790 00791 line[i] = '|'; 00792 line[i+1] = '\0'; 00793 00794 PROFILE_END; 00795 00796 }
static 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.
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 |
References db_gen_exclusion_id(), db_get_exclusion_id_size(), ESUPPL_EXCLUDED, ESUPPL_WAS_TRUE, flag_output_exclusion_ids, gen_char_string(), expression_s::id, malloc_safe, expression_s::op, exp_info_s::op_str, PROFILE, PROFILE_END, expression_s::suppl, and expression_s::ulid.
Referenced by combination_get_missed_expr().
01681 { PROFILE(COMBINATION_EVENT); 01682 01683 char tmp[20]; 01684 unsigned int length; 01685 char* op = exp_op_info[exp->op].op_str; /* Operation string */ 01686 01687 assert( exp != NULL ); 01688 01689 if( (!ESUPPL_WAS_TRUE( exp->suppl ) && !ESUPPL_EXCLUDED( exp->suppl )) || 01690 (ESUPPL_EXCLUDED( exp->suppl ) && show_excluded) ) { 01691 01692 char spaces[30]; 01693 unsigned int rv; 01694 unsigned int eid_size; 01695 01696 if( flag_output_exclusion_ids ) { 01697 eid_size = db_get_exclusion_id_size(); 01698 } 01699 01700 spaces[0] = '\0'; 01701 01702 assert( exp->ulid != -1 ); 01703 01704 /* Allocate memory for info array */ 01705 *info_size = 3; 01706 *info = (char**)malloc_safe( sizeof( char* ) * (*info_size) ); 01707 01708 /* Allocate lines and assign values */ 01709 length = 28; rv = snprintf( tmp, 20, "%d", exp->ulid ); assert( rv < 20 ); length += strlen( tmp ); 01710 if( flag_output_exclusion_ids ) { 01711 length += (eid_size - 1) + 4; 01712 gen_char_string( spaces, ' ', ((eid_size - 1) + 4) ); 01713 } 01714 (*info)[0] = (char*)malloc_safe( length ); 01715 if( flag_output_exclusion_ids ) { 01716 rv = snprintf( (*info)[0], length, " (%s) Expression %d (0/1)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid ); 01717 } else { 01718 rv = snprintf( (*info)[0], length, " Expression %d (0/1)", exp->ulid ); 01719 } 01720 assert( rv < length ); 01721 01722 length = 25 + strlen( op ) + strlen( spaces ); 01723 (*info)[1] = (char*)malloc_safe( length ); rv = snprintf( (*info)[1], length, "%s ^^^^^^^^^^^^^ - %s", spaces, op ); assert( rv < length ); 01724 length = 31 + strlen( spaces ); 01725 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s * Event did not occur", spaces ); assert( rv < length ); 01726 01727 } 01728 01729 PROFILE_END; 01730 01731 }
static bool combination_funit_summary | ( | FILE * | ofile, | |
funit_link * | head, | |||
int * | hits, | |||
int * | total | |||
) | [static] |
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.
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 |
References isuppl_u::assert_ovl, statistic_s::comb_hit, statistic_s::comb_total, combination_display_funit_summary(), FALSE, func_unit_s::filename, funit_link_s::funit, funit_flatten_name(), funit_is_unnamed(), get_basename(), funit_link_s::next, obf_file, obf_funit, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, statistic_s::show, and func_unit_s::stat.
Referenced by combination_report().
00733 { PROFILE(COMBINATION_FUNIT_SUMMARY); 00734 00735 bool miss_found = FALSE; /* Set to TRUE if missing combinations were found */ 00736 00737 while( head != NULL ) { 00738 00739 /* If this is an assertion module, don't output any further */ 00740 if( head->funit->stat->show && !funit_is_unnamed( head->funit ) && 00741 ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( head->funit )) ) { 00742 00743 miss_found |= combination_display_funit_summary( ofile, obf_funit( funit_flatten_name( head->funit ) ), get_basename( obf_file( head->funit->filename ) ), 00744 head->funit->stat->comb_hit, head->funit->stat->comb_total ); 00745 00746 /* Update accumulated information */ 00747 *hits += head->funit->stat->comb_hit; 00748 *total += head->funit->stat->comb_total; 00749 00750 } 00751 00752 head = head->next; 00753 00754 } 00755 00756 PROFILE_END; 00757 00758 return( miss_found ); 00759 00760 }
static void combination_funit_verbose | ( | FILE * | ofile, | |
funit_link * | head | |||
) | [static] |
anonymous | combination_display_verbose |
Outputs the verbose coverage report for the specified functional unit to the specified output stream.
ofile | Pointer to file to output results to | |
head | Pointer to current functional unit to evaluate |
References statistic_s::comb_excluded, statistic_s::comb_hit, statistic_s::comb_total, combination_display_verbose(), combination_reset_counted_exprs(), func_unit_s::filename, free_safe, funit_link_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, funit_link_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, scope_gen_printable(), func_unit_s::stat, and func_unit_s::type.
Referenced by combination_report().
02733 { PROFILE(COMBINATION_FUNIT_VERBOSE); 02734 02735 char* pname; /* Printable version of functional unit name */ 02736 02737 while( head != NULL ) { 02738 02739 if( !funit_is_unnamed( head->funit ) && 02740 (((head->funit->stat->comb_hit < head->funit->stat->comb_total) && !report_covered) || 02741 ((head->funit->stat->comb_hit > 0) && report_covered) || 02742 ((head->funit->stat->comb_excluded > 0) && report_exclusions)) ) { 02743 02744 /* Get printable version of functional unit name */ 02745 pname = scope_gen_printable( funit_flatten_name( head->funit ) ); 02746 02747 fprintf( ofile, "\n" ); 02748 switch( head->funit->type ) { 02749 case FUNIT_MODULE : fprintf( ofile, " Module: " ); break; 02750 case FUNIT_ANAMED_BLOCK : 02751 case FUNIT_NAMED_BLOCK : fprintf( ofile, " Named Block: " ); break; 02752 case FUNIT_AFUNCTION : 02753 case FUNIT_FUNCTION : fprintf( ofile, " Function: " ); break; 02754 case FUNIT_ATASK : 02755 case FUNIT_TASK : fprintf( ofile, " Task: " ); break; 02756 default : fprintf( ofile, " UNKNOWN: " ); break; 02757 } 02758 fprintf( ofile, "%s, File: %s\n", pname, obf_file( head->funit->filename ) ); 02759 fprintf( ofile, " -------------------------------------------------------------------------------------------------------------\n" ); 02760 02761 free_safe( pname, (strlen( pname ) + 1) ); 02762 02763 if( ((head->funit->stat->comb_hit < head->funit->stat->comb_total) && !report_covered) || 02764 ((head->funit->stat->comb_hit > 0) && report_covered && (!report_exclusions || (head->funit->stat->comb_hit > head->funit->stat->comb_excluded))) ) { 02765 combination_display_verbose( ofile, head->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) ); 02766 } 02767 if( (head->funit->stat->comb_excluded > 0) && report_exclusions ) { 02768 combination_reset_counted_exprs( head->funit ); 02769 combination_display_verbose( ofile, head->funit, RPT_TYPE_EXCL ); 02770 } 02771 02772 } 02773 02774 head = head->next; 02775 02776 } 02777 02778 PROFILE_END; 02779 02780 }
void combination_get_coverage | ( | int | exp_id, | |
int | uline_id, | |||
char *** | info, | |||
int * | info_size | |||
) |
Gets output for specified expression including coverage information.
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.
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 |
References combination_get_missed_expr(), exp_link_s::exp, func_unit_s::exp_head, exp_link_find(), expression_find_uline_id(), funit_find_by_id(), PROFILE, PROFILE_END, and TRUE.
03016 { PROFILE(COMBINATION_GET_COVERAGE); 03017 03018 func_unit* funit; /* Pointer to found functional unit */ 03019 exp_link* expl; /* Pointer to current expression link */ 03020 expression* exp; /* Pointer to found expression */ 03021 03022 /* Find the functional unit that contains this expression */ 03023 funit = funit_find_by_id( exp_id ); 03024 assert( funit != NULL ); 03025 03026 /* Find statement containing this expression */ 03027 expl = exp_link_find( exp_id, funit->exp_head ); 03028 assert( expl != NULL ); 03029 03030 /* Now find the subexpression that matches the given underline ID */ 03031 exp = expression_find_uline_id( expl->exp, uline_id ); 03032 assert( exp != NULL ); 03033 03034 combination_get_missed_expr( info, info_size, exp, 0, TRUE ); 03035 03036 PROFILE_END; 03037 03038 }
static 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.
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 |
References ESUPPL_EXCLUDED, exclude_find_exclude_reason(), expression_s::id, expression_s::left, PROFILE, PROFILE_END, realloc_safe, exclude_reason_s::reason, expression_s::right, strdup_safe, expression_s::suppl, and expression_s::ulid.
Referenced by combination_get_expression().
02852 { PROFILE(COMBINATION_GET_EXCLUDE_LIST); 02853 02854 if( exp != NULL ) { 02855 02856 /* Store the exclude value for this expression */ 02857 if( exp->ulid != -1 ) { 02858 02859 exclude_reason* er; 02860 02861 if( (exp->ulid > 0) && ((unsigned int)exp->ulid >= *exclude_size) ) { 02862 int i; 02863 *excludes = (int*)realloc_safe( *excludes, (sizeof( int ) * exp->ulid), (sizeof( int ) * (exp->ulid + 1)) ); 02864 *reasons = (char**)realloc_safe( *reasons, (sizeof( char* ) * exp->ulid), (sizeof( char* ) * (exp->ulid + 1)) ); 02865 for( i=*exclude_size; i<=exp->ulid; i++ ) { 02866 (*excludes)[i] = 0; 02867 (*reasons)[i] = NULL; 02868 } 02869 *exclude_size = exp->ulid + 1; 02870 } 02871 02872 (*excludes)[exp->ulid] = ESUPPL_EXCLUDED( exp->suppl ); 02873 02874 /* If the expression is currently excluded, check to see if there's a reason associated with it */ 02875 if( (ESUPPL_EXCLUDED( exp->suppl ) == 1) && ((er = exclude_find_exclude_reason( 'E', exp->id, funit )) != NULL) ) { 02876 (*reasons)[exp->ulid] = strdup_safe( er->reason ); 02877 } else { 02878 (*reasons)[exp->ulid] = NULL; 02879 } 02880 02881 } 02882 02883 /* Get exclude values for children */ 02884 combination_get_exclude_list( exp->left, funit, excludes, reasons, exclude_size ); 02885 combination_get_exclude_list( exp->right, funit, excludes, reasons, exclude_size ); 02886 02887 } 02888 02889 PROFILE_END; 02890 02891 }
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.
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.
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 |
References Catch_anonymous, codegen_gen_expr(), combination_get_exclude_list(), combination_prep_line(), combination_underline_tree(), exp_link_s::exp, func_unit_s::exp_head, exp_link_find(), free_safe, funit_find_by_id(), funit_get_curr_module(), malloc_safe, expression_s::op, PROFILE, PROFILE_END, realloc_safe, Throw, and Try.
02910 { PROFILE(COMBINATION_GET_EXPRESSION); 02911 02912 exp_link* expl; /* Pointer to found signal link */ 02913 unsigned int tmp; /* Temporary integer (unused) */ 02914 unsigned int i, j; /* Loop iterators */ 02915 char** tmp_ulines; 02916 unsigned int tmp_uline_size; 02917 int start = 0; 02918 unsigned int uline_max = 20; 02919 func_unit* funit; 02920 02921 /* Find functional unit that contains this expression */ 02922 funit = funit_find_by_id( expr_id ); 02923 assert( funit != NULL ); 02924 02925 /* Find the expression itself */ 02926 expl = exp_link_find( expr_id, funit->exp_head ); 02927 assert( expl != NULL ); 02928 02929 /* Generate line of code that missed combinational coverage */ 02930 codegen_gen_expr( expl->exp, expl->exp->op, code, code_size, funit ); 02931 *uline_groups = (int*)malloc_safe( sizeof( int ) * (*code_size) ); 02932 02933 /* Generate exclude information */ 02934 *excludes = NULL; 02935 *reasons = NULL; 02936 *exclude_size = 0; 02937 combination_get_exclude_list( expl->exp, funit_get_curr_module( funit ), excludes, reasons, exclude_size ); 02938 02939 Try { 02940 02941 /* Output underlining feature for missed expressions */ 02942 combination_underline_tree( expl->exp, 0, &tmp_ulines, &tmp_uline_size, &tmp, expl->exp->op, (*code_size == 1), funit ); 02943 02944 } Catch_anonymous { 02945 unsigned int i; 02946 free_safe( *uline_groups, (sizeof( int ) * (*code_size)) ); 02947 *uline_groups = NULL; 02948 for( i=0; i<*code_size; i++ ) { 02949 free_safe( (*code)[i], (strlen( (*code)[i] ) + 1) ); 02950 } 02951 free_safe( *code, (sizeof( char* ) * *code_size) ); 02952 *code = NULL; 02953 *code_size = 0; 02954 free_safe( *excludes, (sizeof( int* ) * *exclude_size) ); 02955 *excludes = NULL; 02956 *exclude_size = 0; 02957 Throw 0; 02958 } 02959 02960 *ulines = (char**)malloc_safe( sizeof( char* ) * uline_max ); 02961 *uline_size = 0; 02962 02963 for( i=0; i<*code_size; i++ ) { 02964 02965 assert( (*code)[i] != NULL ); 02966 02967 (*uline_groups)[i] = 0; 02968 02969 if( *code_size == 1 ) { 02970 *ulines = tmp_ulines; 02971 *uline_size = tmp_uline_size; 02972 (*uline_groups)[0] = tmp_uline_size; 02973 tmp_uline_size = 0; 02974 } else { 02975 for( j=0; j<tmp_uline_size; j++ ) { 02976 if( ((*ulines)[*uline_size] = combination_prep_line( tmp_ulines[j], start, strlen( (*code)[i] ) )) != NULL ) { 02977 ((*uline_groups)[i])++; 02978 (*uline_size)++; 02979 if( *uline_size == uline_max ) { 02980 uline_max += 20; 02981 *ulines = (char**)realloc_safe( *ulines, (sizeof( char* ) * (uline_max - 20)), (sizeof( char* ) * uline_max) ); 02982 } 02983 } 02984 } 02985 } 02986 02987 start += strlen( (*code)[i] ); 02988 02989 } 02990 02991 for( i=0; i<tmp_uline_size; i++ ) { 02992 free_safe( tmp_ulines[i], (strlen( tmp_ulines[i] ) + 1) ); 02993 } 02994 02995 if( tmp_uline_size > 0 ) { 02996 free_safe( tmp_ulines, (sizeof( char* ) * tmp_uline_size) ); 02997 } 02998 02999 PROFILE_END; 03000 03001 }
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
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 |
References statistic_s::comb_excluded, statistic_s::comb_hit, statistic_s::comb_total, PROFILE, PROFILE_END, and func_unit_s::stat.
00569 { PROFILE(COMBINATION_GET_FUNIT_SUMMARY); 00570 00571 *hit = funit->stat->comb_hit; 00572 *excluded = funit->stat->comb_excluded; 00573 *total = funit->stat->comb_total; 00574 00575 PROFILE_END; 00576 00577 }
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
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 |
References statistic_s::comb_excluded, statistic_s::comb_hit, statistic_s::comb_total, PROFILE, PROFILE_END, and funit_inst_s::stat.
00587 { PROFILE(COMBINATION_GET_INST_SUMMARY); 00588 00589 *hit = inst->stat->comb_hit; 00590 *excluded = inst->stat->comb_excluded; 00591 *total = inst->stat->comb_total; 00592 00593 PROFILE_END; 00594 00595 }
static 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.
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 |
References combination_event(), combination_multi_vars(), combination_two_vars(), combination_unary(), ESUPPL_IS_ROOT, EXP_OP_AND, EXP_OP_LAND, EXP_OP_LOR, EXP_OP_OR, expr_stmt_u::expr, EXPR_COMB_MISSED, EXPR_IS_COMB, EXPR_IS_EVENT, expression_s::left, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, report_comb_depth, REPORT_DETAILED, REPORT_VERBOSE, expression_s::right, and expression_s::suppl.
Referenced by combination_get_coverage(), and combination_list_missed().
02418 { PROFILE(COMBINATION_GET_MISSED_EXPR); 02419 02420 assert( exp != NULL ); 02421 02422 *info_size = 0; 02423 02424 if( EXPR_COMB_MISSED( exp ) && 02425 (((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) || 02426 (report_comb_depth == REPORT_VERBOSE)) ) { 02427 02428 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) || 02429 ((exp->op != EXP_OP_AND) && 02430 (exp->op != EXP_OP_LAND) && 02431 (exp->op != EXP_OP_OR) && 02432 (exp->op != EXP_OP_LOR)) ) { 02433 02434 if( (((exp->left != NULL) && 02435 (exp->op == exp->left->op)) || 02436 ((exp->right != NULL) && 02437 (exp->op == exp->right->op))) && 02438 ((exp->op == EXP_OP_AND) || 02439 (exp->op == EXP_OP_OR) || 02440 (exp->op == EXP_OP_LAND) || 02441 (exp->op == EXP_OP_LOR)) ) { 02442 02443 combination_multi_vars( info, info_size, exp, show_excluded ); 02444 02445 } else { 02446 02447 /* Create combination table */ 02448 if( EXPR_IS_COMB( exp ) ) { 02449 combination_two_vars( info, info_size, exp, show_excluded ); 02450 } else if( EXPR_IS_EVENT( exp ) ) { 02451 combination_event( info, info_size, exp, show_excluded ); 02452 } else { 02453 combination_unary( info, info_size, exp, show_excluded ); 02454 } 02455 02456 } 02457 02458 } 02459 02460 } 02461 02462 PROFILE_END; 02463 02464 }
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.
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 |
References combination_get_tree_stats(), statement_s::exp, FALSE, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), funit_is_unnamed(), statement_s::part, PROFILE, PROFILE_END, statement_s::suppl, and TRUE.
Referenced by report_gather_funit_stats(), and report_gather_instance_stats().
00534 { PROFILE(COMBINATION_GET_STATS); 00535 00536 func_iter fi; /* Functional unit iterator */ 00537 statement* stmt; /* Pointer to current statement being examined */ 00538 int ulid; /* Current underline ID for this expression */ 00539 00540 /* If the given functional unit is not an unnamed scope, traverse it now */ 00541 if( !funit_is_unnamed( funit ) ) { 00542 00543 /* Initialize functional unit iterator */ 00544 func_iter_init( &fi, funit, TRUE, FALSE ); 00545 00546 /* Traverse statements in the given functional unit */ 00547 while( (stmt = func_iter_get_next_statement( &fi )) != NULL ) { 00548 ulid = 1; 00549 combination_get_tree_stats( stmt->exp, &ulid, 0, stmt->suppl.part.excluded, hit, excluded, total ); 00550 } 00551 00552 /* Deallocate functional unit iterator */ 00553 func_iter_dealloc( &fi ); 00554 00555 } 00556 00557 PROFILE_END; 00558 00559 }
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.
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 |
References allow_multi_expr, AND_COMB, esuppl_u::comb_cntd, combination_calc_depth(), combination_get_tree_stats(), combination_is_expr_multi_node(), combination_multi_expr_calc(), ESUPPL_EXCLUDED, ESUPPL_IS_ROOT, ESUPPL_WAS_COMB_COUNTED, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_01, esuppl_u::eval_10, esuppl_u::eval_11, EXP_OP_AND, EXP_OP_EXPAND, EXP_OP_LAND, EXP_OP_LOR, EXP_OP_OR, expr_stmt_u::expr, EXPR_IS_COMB, EXPR_IS_EVENT, EXPR_IS_MEASURABLE, expression_is_static_only(), FALSE, exp_info_s::is_comb, expression_s::left, expression_s::op, OR_COMB, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, report_bitwise, report_comb_depth, REPORT_DETAILED, REPORT_SUMMARY, REPORT_VERBOSE, expression_s::right, exp_info_s::suppl, expression_s::suppl, TRUE, expression_s::ulid, expression_s::value, vector_get_eval_ab_count(), vector_get_eval_abc_count(), vector_get_eval_abcd_count(), and vector_s::width.
Referenced by combination_get_stats(), combination_get_tree_stats(), and exclude_expr_assign_and_recalc().
00333 { PROFILE(COMBINATION_GET_TREE_STATS); 00334 00335 int num_hit = 0; /* Number of expression value hits for the current expression */ 00336 int tot_num; /* Total number of combinations for the current expression */ 00337 00338 if( exp != NULL ) { 00339 00340 /* Calculate excluded value for this expression */ 00341 excluded |= ESUPPL_EXCLUDED( exp->suppl ); 00342 00343 /* Calculate children */ 00344 combination_get_tree_stats( exp->left, ulid, combination_calc_depth( exp, curr_depth, TRUE ), excluded, hit, excludes, total ); 00345 combination_get_tree_stats( exp->right, ulid, combination_calc_depth( exp, curr_depth, FALSE ), excluded, hit, excludes, total ); 00346 00347 if( ((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) || 00348 (report_comb_depth == REPORT_VERBOSE) || 00349 (report_comb_depth == REPORT_SUMMARY) ) { 00350 00351 if( (EXPR_IS_MEASURABLE( exp ) == 1) && (ESUPPL_WAS_COMB_COUNTED( exp->suppl ) == 0) ) { 00352 00353 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) || 00354 ((exp->op != EXP_OP_AND) && 00355 (exp->op != EXP_OP_LAND) && 00356 (exp->op != EXP_OP_OR) && 00357 (exp->op != EXP_OP_LOR)) || 00358 !allow_multi_expr ) { 00359 00360 /* Calculate current expression combination coverage */ 00361 if( (((exp->left != NULL) && 00362 (exp->op == exp->left->op)) || 00363 ((exp->right != NULL) && 00364 (exp->op == exp->right->op))) && 00365 ((exp->op == EXP_OP_AND) || 00366 (exp->op == EXP_OP_OR) || 00367 (exp->op == EXP_OP_LAND) || 00368 (exp->op == EXP_OP_LOR)) && allow_multi_expr ) { 00369 combination_multi_expr_calc( exp, ulid, FALSE, excluded, hit, excludes, total ); 00370 } else { 00371 if( !expression_is_static_only( exp ) ) { 00372 if( EXPR_IS_COMB( exp ) == 1 ) { 00373 if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) { 00374 if( report_bitwise ) { 00375 tot_num = 3 * exp->value->width; 00376 num_hit = vector_get_eval_abc_count( exp->value ); 00377 } else { 00378 tot_num = 3; 00379 num_hit = ESUPPL_WAS_FALSE( exp->left->suppl ) + 00380 ESUPPL_WAS_FALSE( exp->right->suppl ) + 00381 exp->suppl.part.eval_11; 00382 } 00383 } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) { 00384 if( report_bitwise ) { 00385 tot_num = 3 * exp->value->width; 00386 num_hit = vector_get_eval_abc_count( exp->value ); 00387 } else { 00388 tot_num = 3; 00389 num_hit = ESUPPL_WAS_TRUE( exp->left->suppl ) + 00390 ESUPPL_WAS_TRUE( exp->right->suppl ) + 00391 exp->suppl.part.eval_00; 00392 } 00393 } else { 00394 if( report_bitwise ) { 00395 tot_num = 4 * exp->value->width; 00396 num_hit = vector_get_eval_abcd_count( exp->value ); 00397 } else { 00398 tot_num = 4; 00399 num_hit = exp->suppl.part.eval_00 + 00400 exp->suppl.part.eval_01 + 00401 exp->suppl.part.eval_10 + 00402 exp->suppl.part.eval_11; 00403 } 00404 } 00405 *total += tot_num; 00406 if( excluded ) { 00407 *hit += tot_num; 00408 *excludes += tot_num; 00409 } else { 00410 *hit += num_hit; 00411 } 00412 if( (num_hit != tot_num) && (exp->ulid == -1) && !combination_is_expr_multi_node( exp ) ) { 00413 exp->ulid = *ulid; 00414 (*ulid)++; 00415 } 00416 } else if( EXPR_IS_EVENT( exp ) == 1 ) { 00417 (*total)++; 00418 num_hit = ESUPPL_WAS_TRUE( exp->suppl ); 00419 if( excluded ) { 00420 (*hit)++; 00421 (*excludes)++; 00422 } else { 00423 *hit += num_hit; 00424 } 00425 if( (num_hit != 1) && (exp->ulid == -1) && !combination_is_expr_multi_node( exp ) ) { 00426 exp->ulid = *ulid; 00427 (*ulid)++; 00428 } 00429 } else { 00430 if( (exp->op != EXP_OP_EXPAND) || (exp->value->width > 0) ) { 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 00459 /* Consider this expression to be counted */ 00460 exp->suppl.part.comb_cntd = 1; 00461 00462 } 00463 00464 PROFILE_END; 00465 00466 }
static bool combination_instance_summary | ( | FILE * | ofile, | |
funit_inst * | root, | |||
char * | parent, | |||
int * | hits, | |||
int * | total | |||
) | [static] |
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.
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 |
References isuppl_u::assert_ovl, funit_inst_s::child_head, statistic_s::comb_hit, statistic_s::comb_total, combination_display_instance_summary(), db_is_unnamed_scope(), FALSE, free_safe, funit_inst_s::funit, funit_is_unnamed(), funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, obf_inst, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, scope_gen_printable(), statistic_s::show, funit_inst_s::stat, and funit_inst_s::suppl.
Referenced by combination_report().
00638 { PROFILE(COMBINATION_INSTANCE_SUMMARY); 00639 00640 funit_inst* curr; /* Pointer to current child functional unit instance of this node */ 00641 char tmpname[4096]; /* Temporary name holder of instance */ 00642 char* pname; /* Printable version of instance name */ 00643 bool miss_found = FALSE; /* Set to TRUE if a logical combination was missed */ 00644 00645 assert( root != NULL ); 00646 assert( root->stat != NULL ); 00647 00648 /* Generate printable version of instance name */ 00649 pname = scope_gen_printable( root->name ); 00650 00651 if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) { 00652 strcpy( tmpname, parent ); 00653 } else if( strcmp( parent, "*" ) == 0 ) { 00654 strcpy( tmpname, pname ); 00655 } else { 00656 unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent, obf_inst( pname ) ); 00657 assert( rv < 4096 ); 00658 } 00659 00660 free_safe( pname, (strlen( pname ) + 1) ); 00661 00662 if( (root->funit != NULL) && root->stat->show && !funit_is_unnamed( root->funit ) && 00663 ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit )) ) { 00664 00665 miss_found |= combination_display_instance_summary( ofile, tmpname, root->stat->comb_hit, root->stat->comb_total ); 00666 00667 /* Update accumulated information */ 00668 *hits += root->stat->comb_hit; 00669 *total += root->stat->comb_total; 00670 00671 } 00672 00673 /* If this is an assertion module, don't output any further */ 00674 if( (info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit ) ) { 00675 00676 curr = root->child_head; 00677 while( curr != NULL ) { 00678 miss_found |= combination_instance_summary( ofile, curr, tmpname, hits, total ); 00679 curr = curr->next; 00680 } 00681 00682 } 00683 00684 PROFILE_END; 00685 00686 return( miss_found ); 00687 00688 }
static void combination_instance_verbose | ( | FILE * | ofile, | |
funit_inst * | root, | |||
char * | parent | |||
) | [static] |
anonymous | combination_display_verbose combination_instance_verbose |
Outputs the verbose coverage report for the specified functional unit instance to the specified output stream.
ofile | Pointer to file to output results to | |
root | Pointer to current functional unit instance to evaluate | |
parent | Name of parent instance |
References funit_inst_s::child_head, statistic_s::comb_excluded, statistic_s::comb_hit, statistic_s::comb_total, combination_display_verbose(), combination_reset_counted_exprs(), db_is_unnamed_scope(), func_unit_s::filename, free_safe, funit_inst_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, scope_gen_printable(), funit_inst_s::stat, funit_inst_s::suppl, and func_unit_s::type.
Referenced by combination_report().
02657 { PROFILE(COMBINATION_INSTANCE_VERBOSE); 02658 02659 funit_inst* curr_inst; /* Pointer to current instance being evaluated */ 02660 char tmpname[4096]; /* Temporary name holder of instance */ 02661 char* pname; /* Printable version of instance name */ 02662 02663 assert( root != NULL ); 02664 02665 /* Get printable version of instance name */ 02666 pname = scope_gen_printable( root->name ); 02667 02668 if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) { 02669 strcpy( tmpname, parent ); 02670 } else if( strcmp( parent, "*" ) == 0 ) { 02671 strcpy( tmpname, pname ); 02672 } else { 02673 unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent, pname ); 02674 assert( rv < 4096 ); 02675 } 02676 02677 free_safe( pname, (strlen( pname ) + 1) ); 02678 02679 if( (root->funit != NULL) && !funit_is_unnamed( root->funit ) && 02680 (((root->stat->comb_hit < root->stat->comb_total) && !report_covered) || 02681 ((root->stat->comb_hit > 0) && report_covered) || 02682 ((root->stat->comb_excluded > 0) && report_exclusions)) ) { 02683 02684 /* Get printable version of functional unit name */ 02685 pname = scope_gen_printable( funit_flatten_name( root->funit ) ); 02686 02687 fprintf( ofile, "\n" ); 02688 switch( root->funit->type ) { 02689 case FUNIT_MODULE : fprintf( ofile, " Module: " ); break; 02690 case FUNIT_ANAMED_BLOCK : 02691 case FUNIT_NAMED_BLOCK : fprintf( ofile, " Named Block: " ); break; 02692 case FUNIT_AFUNCTION : 02693 case FUNIT_FUNCTION : fprintf( ofile, " Function: " ); break; 02694 case FUNIT_ATASK : 02695 case FUNIT_TASK : fprintf( ofile, " Task: " ); break; 02696 default : fprintf( ofile, " UNKNOWN: " ); break; 02697 } 02698 fprintf( ofile, "%s, File: %s, Instance: %s\n", pname, obf_file( root->funit->filename ), tmpname ); 02699 fprintf( ofile, " -------------------------------------------------------------------------------------------------------------\n" ); 02700 02701 free_safe( pname, (strlen( pname ) + 1) ); 02702 02703 if( ((root->stat->comb_hit < root->stat->comb_total) && !report_covered) || 02704 ((root->stat->comb_hit > 0) && report_covered && (!report_exclusions || (root->stat->comb_hit > root->stat->comb_excluded))) ) { 02705 combination_display_verbose( ofile, root->funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) ); 02706 } 02707 if( report_exclusions && (root->stat->comb_excluded > 0) ) { 02708 combination_reset_counted_exprs( root->funit ); 02709 combination_display_verbose( ofile, root->funit, RPT_TYPE_EXCL ); 02710 } 02711 02712 } 02713 02714 curr_inst = root->child_head; 02715 while( curr_inst != NULL ) { 02716 combination_instance_verbose( ofile, curr_inst, tmpname ); 02717 curr_inst = curr_inst->next; 02718 } 02719 02720 PROFILE_END; 02721 02722 }
static bool combination_is_expr_multi_node | ( | expression * | exp | ) | [static] |
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.
exp | Pointer to expression to evaluate |
References ESUPPL_IS_ROOT, EXP_OP_AND, EXP_OP_LAND, EXP_OP_LOR, EXP_OP_OR, expr_stmt_u::expr, expression_s::id, expression_s::left, expression_s::op, expression_s::parent, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, and expression_s::ulid.
Referenced by combination_get_tree_stats().
00295 { PROFILE(COMBINATION_IS_EXPR_MULTI_NODE); 00296 00297 bool retval = (exp != NULL) && 00298 (ESUPPL_IS_ROOT( exp->suppl ) == 0) && 00299 (exp->parent->expr->left != NULL) && 00300 (exp->parent->expr->right != NULL) && 00301 ( ( (exp->parent->expr->right->id == exp->id) && 00302 (exp->parent->expr->left->ulid == -1) ) || 00303 (exp->parent->expr->left->id == exp->id) ) && 00304 ( (exp->parent->expr->op == EXP_OP_AND) || 00305 (exp->parent->expr->op == EXP_OP_LAND) || 00306 (exp->parent->expr->op == EXP_OP_OR) || 00307 (exp->parent->expr->op == EXP_OP_LOR) ) && 00308 ( ( (ESUPPL_IS_ROOT( exp->parent->expr->suppl ) == 0) && 00309 (exp->parent->expr->op == exp->parent->expr->parent->expr->op) ) || 00310 (exp->parent->expr->left->op == exp->parent->expr->op) ); 00311 00312 PROFILE_END; 00313 00314 return( retval ); 00315 00316 }
static 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.
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 |
References combination_calc_depth(), combination_get_missed_expr(), db_get_exclusion_id_size(), exclude_find_exclude_reason(), FALSE, flag_output_exclusion_ids, free_safe, expression_s::id, expression_s::left, PROFILE, PROFILE_END, exclude_reason_s::reason, report_exclusions, report_output_exclusion_reason(), expression_s::right, and TRUE.
Referenced by combination_display_verbose().
02478 { PROFILE(COMBINATION_LIST_MISSED); 02479 02480 char** info; /* String array containing combination coverage information for this expression */ 02481 int info_size; /* Specifies the number of valid entries in the info array */ 02482 int i; /* Loop iterator */ 02483 02484 if( exp != NULL ) { 02485 02486 exclude_reason* er; 02487 02488 combination_list_missed( ofile, exp->left, combination_calc_depth( exp, curr_depth, TRUE ), funit, show_exclusions ); 02489 combination_list_missed( ofile, exp->right, combination_calc_depth( exp, curr_depth, FALSE ), funit, show_exclusions ); 02490 02491 /* Get coverage information for this expression */ 02492 combination_get_missed_expr( &info, &info_size, exp, curr_depth, show_exclusions ); 02493 02494 /* If there was any coverage information for this expression, output it to the specified output stream */ 02495 if( info_size > 0 ) { 02496 02497 for( i=0; i<info_size; i++ ) { 02498 02499 fprintf( ofile, "%s\n", info[i] ); 02500 free_safe( info[i], (strlen( info[i] ) + 1) ); 02501 02502 } 02503 02504 /* Output the exclusion reason information, if it exists */ 02505 if( report_exclusions && (er = exclude_find_exclude_reason( 'E', exp->id, funit )) != NULL ) { 02506 if( flag_output_exclusion_ids ) { 02507 report_output_exclusion_reason( ofile, (14 + (db_get_exclusion_id_size() - 1)), er->reason, TRUE ); 02508 } else { 02509 report_output_exclusion_reason( ofile, 10, er->reason, TRUE ); 02510 } 02511 } 02512 02513 fprintf( ofile, "\n" ); 02514 02515 free_safe( info, (sizeof( char* ) * info_size) ); 02516 02517 } 02518 02519 } 02520 02521 PROFILE_END; 02522 02523 }
static 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.
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 |
References combination_does_multi_exp_need_ul(), ESUPPL_EXCLUDED, ESUPPL_IS_ROOT, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_11, EXP_OP_AND, EXP_OP_LAND, expr_stmt_u::expr, expression_s::left, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, and expression_s::ulid.
Referenced by combination_get_tree_stats(), and combination_multi_vars().
00200 { PROFILE(COMBINATION_MULTI_EXPR_CALC); 00201 00202 bool and_op; /* Specifies if current expression is an AND or LAND operation */ 00203 00204 if( exp != NULL ) { 00205 00206 /* Calculate this expression's exclusion */ 00207 excluded |= ESUPPL_EXCLUDED( exp->suppl ); 00208 00209 /* Figure out if this is an AND/LAND operation */ 00210 and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND); 00211 00212 /* Decide if our expression requires that this sequence gets underlined */ 00213 if( !ul ) { 00214 ul = combination_does_multi_exp_need_ul( exp ); 00215 } 00216 00217 if( (exp->left != NULL) && (exp->op != exp->left->op) ) { 00218 if( excluded ) { 00219 (*hit)++; 00220 (*excludes)++; 00221 } else { 00222 if( and_op ) { 00223 *hit += ESUPPL_WAS_FALSE( exp->left->suppl ); 00224 } else { 00225 *hit += ESUPPL_WAS_TRUE( exp->left->suppl ); 00226 } 00227 } 00228 if( (exp->left->ulid == -1) && ul ) { 00229 exp->left->ulid = *ulid; 00230 (*ulid)++; 00231 } 00232 (*total)++; 00233 } else { 00234 combination_multi_expr_calc( exp->left, ulid, ul, excluded, hit, excludes, total ); 00235 } 00236 00237 if( (exp->right != NULL) && (exp->op != exp->right->op) ) { 00238 if( excluded ) { 00239 (*hit)++; 00240 (*excludes)++; 00241 } else { 00242 if( and_op ) { 00243 *hit += ESUPPL_WAS_FALSE( exp->right->suppl ); 00244 } else { 00245 *hit += ESUPPL_WAS_TRUE( exp->right->suppl ); 00246 } 00247 } 00248 if( (exp->right->ulid == -1) && ul ) { 00249 exp->right->ulid = *ulid; 00250 (*ulid)++; 00251 } 00252 (*total)++; 00253 } else { 00254 combination_multi_expr_calc( exp->right, ulid, ul, excluded, hit, excludes, total ); 00255 } 00256 00257 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ) { 00258 if( excluded ) { 00259 (*hit)++; 00260 (*excludes)++; 00261 } else { 00262 if( and_op ) { 00263 *hit += exp->suppl.part.eval_11; 00264 } else { 00265 *hit += exp->suppl.part.eval_00; 00266 } 00267 } 00268 if( (exp->ulid == -1) && ul ) { 00269 exp->ulid = *ulid; 00270 (*ulid)++; 00271 } 00272 (*total)++; 00273 } 00274 00275 } 00276 00277 PROFILE_END; 00278 00279 }
static 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.
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 |
References db_get_exclusion_id_size(), flag_output_exclusion_ids, gen_char_string(), line_width, malloc_safe, PROFILE, and PROFILE_END.
Referenced by combination_multi_vars().
02190 { PROFILE(COMBINATION_MULTI_EXPR_OUTPUT); 02191 02192 int start = 0; 02193 int i; 02194 int len = strlen( line1 ); 02195 int info_index = 2; 02196 unsigned int eid_size; 02197 02198 if( flag_output_exclusion_ids ) { 02199 eid_size = db_get_exclusion_id_size(); 02200 } 02201 02202 for( i=0; i<len; i++ ) { 02203 02204 if( (i + 1) == len ) { 02205 02206 unsigned int rv; 02207 unsigned int slen1 = strlen( line1 + start ) + 9; 02208 unsigned int slen2 = strlen( line2 + start ) + 9; 02209 unsigned int slen3 = strlen( line3 + start ) + 9; 02210 02211 if( flag_output_exclusion_ids ) { 02212 slen1 += (eid_size - 1) + 4; 02213 slen2 += (eid_size - 1) + 4; 02214 slen3 += (eid_size - 1) + 4; 02215 } 02216 02217 info[info_index+0] = (char*)malloc_safe( slen1 ); 02218 info[info_index+1] = (char*)malloc_safe( slen2 ); 02219 info[info_index+2] = (char*)malloc_safe( slen3 ); 02220 02221 if( flag_output_exclusion_ids ) { 02222 char tmp[30]; 02223 gen_char_string( tmp, ' ', ((eid_size - 1) + 4) ); 02224 rv = snprintf( info[info_index+0], slen1, "%s %s", tmp, (line1 + start) ); 02225 assert( rv < slen1 ); 02226 rv = snprintf( info[info_index+1], slen2, "%s %s", tmp, (line2 + start) ); 02227 assert( rv < slen2 ); 02228 rv = snprintf( info[info_index+2], slen3, "%s %s", tmp, (line3 + start) ); 02229 assert( rv < slen3 ); 02230 } else { 02231 rv = snprintf( info[info_index+0], slen1, " %s", (line1 + start) ); 02232 assert( rv < slen1 ); 02233 rv = snprintf( info[info_index+1], slen2, " %s", (line2 + start) ); 02234 assert( rv < slen2 ); 02235 rv = snprintf( info[info_index+2], slen3, " %s", (line3 + start) ); 02236 assert( rv < slen3 ); 02237 } 02238 02239 } else if( (line1[i] == '|') && ((i - start) >= line_width) ) { 02240 02241 unsigned int rv; 02242 unsigned int slen1; 02243 unsigned int slen2; 02244 unsigned int slen3; 02245 02246 line1[i] = '\0'; 02247 line2[i] = '\0'; 02248 line3[i] = '\0'; 02249 02250 slen1 = strlen( line1 + start ) + 10; 02251 slen2 = strlen( line2 + start ) + 10; 02252 slen3 = strlen( line3 + start ) + 11; 02253 02254 if( flag_output_exclusion_ids ) { 02255 slen1 += (eid_size - 1) + 4; 02256 slen2 += (eid_size - 1) + 4; 02257 slen3 += (eid_size - 1) + 4; 02258 } 02259 02260 info[info_index+0] = (char*)malloc_safe( slen1 ); 02261 info[info_index+1] = (char*)malloc_safe( slen2 ); 02262 info[info_index+2] = (char*)malloc_safe( slen3 ); 02263 02264 if( flag_output_exclusion_ids ) { 02265 char tmp[30]; 02266 gen_char_string( tmp, ' ', ((eid_size - 1) + 4) ); 02267 rv = snprintf( info[info_index+0], slen1, "%s %s|", tmp, (line1 + start) ); 02268 assert( rv < slen1 ); 02269 rv = snprintf( info[info_index+1], slen2, "%s %s|", tmp, (line2 + start) ); 02270 assert( rv < slen2 ); 02271 rv = snprintf( info[info_index+2], slen3, "%s %s \n", tmp, (line3 + start) ); 02272 assert( rv < slen3 ); 02273 } else { 02274 rv = snprintf( info[info_index+0], slen1, " %s|", (line1 + start) ); 02275 assert( rv < slen1 ); 02276 rv = snprintf( info[info_index+1], slen2, " %s|", (line2 + start) ); 02277 assert( rv < slen2 ); 02278 rv = snprintf( info[info_index+2], slen3, " %s \n", (line3 + start) ); 02279 assert( rv < slen3 ); 02280 } 02281 02282 start = i + 1; 02283 info_index += 3; 02284 02285 } 02286 02287 } 02288 02289 PROFILE_END; 02290 02291 }
static int combination_multi_expr_output_length | ( | char * | line1 | ) | [static] |
line1 | First line of multi-variable expression output |
References line_width, PROFILE, and PROFILE_END.
Referenced by combination_multi_vars().
02160 { PROFILE(COMBINATION_MULTI_EXPR_OUTPUT_LENGTH); 02161 02162 int start = 0; 02163 int i; 02164 int len = strlen( line1 ); 02165 int length = 0; 02166 02167 for( i=0; i<len; i++ ) { 02168 if( (i + 1) == len ) { 02169 length += 3; 02170 } else if( (line1[i] == '|') && ((i - start) >= line_width) ) { 02171 length += 3; 02172 start = i + 1; 02173 } 02174 } 02175 02176 PROFILE_END; 02177 02178 return( length ); 02179 02180 }
static 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.
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 |
References ESUPPL_IS_ROOT, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_11, EXP_OP_AND, EXP_OP_LAND, expr_stmt_u::expr, free_safe, expression_s::left, malloc_safe, expression_s::op, expression_s::parent, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, expression_s::suppl, and expression_s::ulid.
Referenced by combination_multi_vars().
01985 { PROFILE(COMBINATION_MULTI_VAR_EXPRS); 01986 01987 char* left_line1 = NULL; 01988 char* left_line2 = NULL; 01989 char* left_line3 = NULL; 01990 char* right_line1 = NULL; 01991 char* right_line2 = NULL; 01992 char* right_line3 = NULL; 01993 char curr_id_str[20]; 01994 unsigned int curr_id_str_len; 01995 unsigned int i; 01996 bool and_op; 01997 unsigned int rv; /* Return value from snprintf calls */ 01998 01999 if( exp != NULL ) { 02000 02001 and_op = (exp->op == EXP_OP_AND) || (exp->op == EXP_OP_LAND); 02002 02003 /* If we have hit the left-most expression, start creating string here */ 02004 if( (exp->left != NULL) && (exp->op != exp->left->op) ) { 02005 02006 assert( exp->left->ulid != -1 ); 02007 rv = snprintf( curr_id_str, 20, "%d", exp->left->ulid ); 02008 assert( rv < 20 ); 02009 curr_id_str_len = strlen( curr_id_str ); 02010 left_line1 = (char*)malloc_safe( curr_id_str_len + 4 ); 02011 left_line2 = (char*)malloc_safe( curr_id_str_len + 4 ); 02012 left_line3 = (char*)malloc_safe( curr_id_str_len + 4 ); 02013 rv = snprintf( left_line1, (curr_id_str_len + 4), " %s |", curr_id_str ); 02014 assert( rv < (curr_id_str_len + 4) ); 02015 for( i=0; i<(curr_id_str_len-1); i++ ) { 02016 curr_id_str[i] = '='; 02017 } 02018 curr_id_str[i] = '\0'; 02019 if( and_op ) { 02020 rv = snprintf( left_line2, (curr_id_str_len + 4), "=0%s=|", curr_id_str ); 02021 assert( rv < (curr_id_str_len + 4) ); 02022 } else { 02023 rv = snprintf( left_line2, (curr_id_str_len + 4), "=1%s=|", curr_id_str ); 02024 assert( rv < (curr_id_str_len + 4) ); 02025 } 02026 for( i=0; i<(curr_id_str_len - 1); i++ ) { 02027 curr_id_str[i] = ' '; 02028 } 02029 curr_id_str[i] = '\0'; 02030 if( and_op ) { 02031 rv = snprintf( left_line3, (curr_id_str_len + 4), " %c%s ", ((ESUPPL_WAS_FALSE( exp->left->suppl ) == 1) ? ' ' : '*'), curr_id_str ); 02032 assert( rv < (curr_id_str_len + 4) ); 02033 } else { 02034 rv = snprintf( left_line3, (curr_id_str_len + 4), " %c%s ", ((ESUPPL_WAS_TRUE( exp->left->suppl ) == 1) ? ' ' : '*'), curr_id_str ); 02035 assert( rv < (curr_id_str_len + 4) ); 02036 } 02037 02038 } else { 02039 02040 combination_multi_var_exprs( &left_line1, &left_line2, &left_line3, exp->left ); 02041 02042 } 02043 02044 /* Get right-side information */ 02045 if( (exp->right != NULL) && (exp->op != exp->right->op) ) { 02046 02047 assert( exp->right->ulid != -1 ); 02048 rv = snprintf( curr_id_str, 20, "%d", exp->right->ulid ); 02049 assert( rv < 20 ); 02050 curr_id_str_len = strlen( curr_id_str ); 02051 right_line1 = (char*)malloc_safe( curr_id_str_len + 4 ); 02052 right_line2 = (char*)malloc_safe( curr_id_str_len + 4 ); 02053 right_line3 = (char*)malloc_safe( curr_id_str_len + 4 ); 02054 rv = snprintf( right_line1, (curr_id_str_len + 4), " %s |", curr_id_str ); 02055 assert( rv < (curr_id_str_len + 4) ); 02056 for( i=0; i<(curr_id_str_len-1); i++ ) { 02057 curr_id_str[i] = '='; 02058 } 02059 curr_id_str[i] = '\0'; 02060 if( and_op ) { 02061 rv = snprintf( right_line2, (curr_id_str_len + 4), "=0%s=|", curr_id_str ); 02062 assert( rv < (curr_id_str_len + 4) ); 02063 } else { 02064 rv = snprintf( right_line2, (curr_id_str_len + 4), "=1%s=|", curr_id_str ); 02065 assert( rv < (curr_id_str_len + 4) ); 02066 } 02067 for( i=0; i<(curr_id_str_len - 1); i++ ) { 02068 curr_id_str[i] = ' '; 02069 } 02070 curr_id_str[i] = '\0'; 02071 if( and_op ) { 02072 rv = snprintf( right_line3, (curr_id_str_len + 4), " %c%s ", ((ESUPPL_WAS_FALSE( exp->right->suppl ) == 1) ? ' ' : '*'), curr_id_str ); 02073 assert( rv < (curr_id_str_len + 4) ); 02074 } else { 02075 rv = snprintf( right_line3, (curr_id_str_len + 4), " %c%s ", ((ESUPPL_WAS_TRUE( exp->right->suppl ) == 1) ? ' ' : '*'), curr_id_str ); 02076 assert( rv < (curr_id_str_len + 4) ); 02077 } 02078 02079 } else { 02080 02081 combination_multi_var_exprs( &right_line1, &right_line2, &right_line3, exp->right ); 02082 02083 } 02084 02085 if( left_line1 != NULL ) { 02086 if( right_line1 != NULL ) { 02087 unsigned int slen1 = strlen( left_line1 ) + strlen( right_line1 ) + 1; 02088 unsigned int slen2 = strlen( left_line2 ) + strlen( right_line2 ) + 1; 02089 unsigned int slen3 = strlen( left_line3 ) + strlen( right_line3 ) + 1; 02090 *line1 = (char*)malloc_safe( slen1 ); 02091 *line2 = (char*)malloc_safe( slen2 ); 02092 *line3 = (char*)malloc_safe( slen3 ); 02093 rv = snprintf( *line1, slen1, "%s%s", left_line1, right_line1 ); 02094 assert( rv < slen1 ); 02095 rv = snprintf( *line2, slen2, "%s%s", left_line2, right_line2 ); 02096 assert( rv < slen2 ); 02097 rv = snprintf( *line3, slen3, "%s%s", left_line3, right_line3 ); 02098 assert( rv < slen3 ); 02099 free_safe( left_line1, (strlen( left_line1 ) + 1) ); 02100 free_safe( left_line2, (strlen( left_line2 ) + 1) ); 02101 free_safe( left_line3, (strlen( left_line3 ) + 1) ); 02102 free_safe( right_line1, (strlen( right_line1 ) + 1) ); 02103 free_safe( right_line2, (strlen( right_line2 ) + 1) ); 02104 free_safe( right_line3, (strlen( right_line3 ) + 1) ); 02105 } else { 02106 *line1 = left_line1; 02107 *line2 = left_line2; 02108 *line3 = left_line3; 02109 } 02110 } else { 02111 assert( right_line1 != NULL ); 02112 *line1 = right_line1; 02113 *line2 = right_line2; 02114 *line3 = right_line3; 02115 } 02116 02117 /* If we are the root, output all value */ 02118 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || (exp->op != exp->parent->expr->op) ) { 02119 unsigned int slen1 = strlen( *line1 ) + 5; 02120 unsigned int slen2 = strlen( *line2 ) + 6; 02121 unsigned int slen3 = strlen( *line3 ) + 6; 02122 left_line1 = *line1; 02123 left_line2 = *line2; 02124 left_line3 = *line3; 02125 *line1 = (char*)malloc_safe( slen1 ); 02126 *line2 = (char*)malloc_safe( slen2 ); 02127 *line3 = (char*)malloc_safe( slen3 ); 02128 if( and_op ) { 02129 rv = snprintf( *line1, slen1, "%s All", left_line1 ); 02130 assert( rv < slen1 ); 02131 rv = snprintf( *line2, slen2, "%s==1==", left_line2 ); 02132 assert( rv < slen2 ); 02133 rv = snprintf( *line3, slen3, "%s %c ", left_line3, ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') ); 02134 assert( rv < slen3 ); 02135 } else { 02136 rv = snprintf( *line1, slen1, "%s All", left_line1 ); 02137 assert( rv < slen1 ); 02138 rv = snprintf( *line2, slen2, "%s==0==", left_line2 ); 02139 assert( rv < slen2 ); 02140 rv = snprintf( *line3, slen3, "%s %c ", left_line3, ((exp->suppl.part.eval_00 == 1) ? ' ' : '*') ); 02141 assert( rv < slen3 ); 02142 } 02143 free_safe( left_line1, (strlen( left_line1 ) + 1) ); 02144 free_safe( left_line2, (strlen( left_line2 ) + 1) ); 02145 free_safe( left_line3, (strlen( left_line3 ) + 1) ); 02146 } 02147 02148 } 02149 02150 PROFILE_END; 02151 02152 }
static 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.
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 |
References combination_multi_expr_calc(), combination_multi_expr_output(), combination_multi_expr_output_length(), combination_multi_var_exprs(), db_gen_exclusion_id(), db_get_exclusion_id_size(), ESUPPL_EXCLUDED, EXP_OP_AND, EXP_OP_LAND, EXP_OP_LOR, EXP_OP_OR, FALSE, flag_output_exclusion_ids, free_safe, gen_char_string(), expression_s::id, malloc_safe, expression_s::op, PROFILE, PROFILE_END, strdup_safe, expression_s::suppl, and expression_s::ulid.
Referenced by combination_get_missed_expr().
02302 { PROFILE(COMBINATION_MULTI_VARS); 02303 02304 int ulid = 1; 02305 unsigned int hit = 0; 02306 unsigned int excluded = 0; 02307 unsigned int total = 0; 02308 char* line1 = NULL; 02309 char* line2 = NULL; 02310 char* line3 = NULL; 02311 char tmp[20]; 02312 unsigned int line_size = 1; 02313 02314 /* Only output this expression if we are missing coverage. */ 02315 if( exp->ulid != -1 ) { 02316 02317 /* Calculate hit and total values for this sub-expression */ 02318 combination_multi_expr_calc( exp, &ulid, FALSE, FALSE, &hit, &excluded, &total ); 02319 02320 if( ((hit != total) && !ESUPPL_EXCLUDED( exp->suppl )) || 02321 (ESUPPL_EXCLUDED( exp->suppl ) && show_excluded) ) { 02322 02323 unsigned int rv; 02324 unsigned int slen1; 02325 unsigned int slen2; 02326 unsigned int slen3; 02327 unsigned int eid_size; 02328 02329 if( flag_output_exclusion_ids ) { 02330 eid_size = db_get_exclusion_id_size(); 02331 } 02332 02333 /* Gather report output for this expression */ 02334 combination_multi_var_exprs( &line1, &line2, &line3, exp ); 02335 02336 /* Get the lengths of the original string lengths -- these strings will be possibly altered by combination_multi_expr_output */ 02337 slen1 = strlen( line1 ) + 1; 02338 slen2 = strlen( line2 ) + 1; 02339 slen3 = strlen( line3 ) + 1; 02340 02341 /* Calculate the array needed to store the output information and allocate this memory */ 02342 *info_size = combination_multi_expr_output_length( line1 ) + 2; 02343 *info = (char**)malloc_safe( sizeof( char* ) * (*info_size) ); 02344 02345 /* Calculate needed line length */ 02346 rv = snprintf( tmp, 20, "%u", hit ); 02347 assert( rv < 20 ); 02348 line_size += strlen( tmp ); 02349 rv = snprintf( tmp, 20, "%u", total ); 02350 assert( rv < 20 ); 02351 line_size += strlen( tmp ); 02352 rv = snprintf( tmp, 20, "%d", exp->ulid ); 02353 assert( rv < 20 ); 02354 line_size += strlen( tmp ); 02355 line_size += 25; /* Number of additional characters in line below */ 02356 if( flag_output_exclusion_ids ) { 02357 line_size += (eid_size - 1) + 4; 02358 } 02359 (*info)[0] = (char*)malloc_safe( line_size ); 02360 02361 if( flag_output_exclusion_ids ) { 02362 char* tmp; 02363 char spaces[30]; 02364 int size; 02365 rv = snprintf( (*info)[0], line_size, " (%s) Expression %d (%u/%u)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, total ); 02366 assert( rv < line_size ); 02367 switch( exp->op ) { 02368 case EXP_OP_AND : tmp = strdup_safe( " ^^^^^^^^^^^^^ - &" ); break; 02369 case EXP_OP_OR : tmp = strdup_safe( " ^^^^^^^^^^^^^ - |" ); break; 02370 case EXP_OP_LAND : tmp = strdup_safe( " ^^^^^^^^^^^^^ - &&" ); break; 02371 case EXP_OP_LOR : tmp = strdup_safe( " ^^^^^^^^^^^^^ - ||" ); break; 02372 default : assert( 0 ); break; 02373 } 02374 size = strlen( tmp ) + (eid_size - 1) + 5; 02375 gen_char_string( spaces, ' ', (eid_size - 1) ); 02376 (*info)[1] = (char*)malloc_safe( size ); 02377 rv = snprintf( (*info)[1], size, "%s %s", spaces, tmp ); 02378 assert( rv < size ); 02379 free_safe( tmp, (strlen( tmp ) + 1) ); 02380 } else { 02381 rv = snprintf( (*info)[0], line_size, " Expression %d (%u/%u)", exp->ulid, hit, total ); 02382 assert( rv < line_size ); 02383 switch( exp->op ) { 02384 case EXP_OP_AND : (*info)[1] = strdup_safe( " ^^^^^^^^^^^^^ - &" ); break; 02385 case EXP_OP_OR : (*info)[1] = strdup_safe( " ^^^^^^^^^^^^^ - |" ); break; 02386 case EXP_OP_LAND : (*info)[1] = strdup_safe( " ^^^^^^^^^^^^^ - &&" ); break; 02387 case EXP_OP_LOR : (*info)[1] = strdup_safe( " ^^^^^^^^^^^^^ - ||" ); break; 02388 default : assert( 0 ); break; 02389 } 02390 } 02391 02392 /* Output the lines paying attention to the current line width */ 02393 combination_multi_expr_output( *info, line1, line2, line3 ); 02394 02395 free_safe( line1, slen1 ); 02396 free_safe( line2, slen2 ); 02397 free_safe( line3, slen3 ); 02398 02399 } 02400 02401 } 02402 02403 PROFILE_END; 02404 02405 }
static 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.
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 |
References esuppl_u::comb_cntd, combination_calc_depth(), ESUPPL_EXCLUDED, ESUPPL_WAS_COMB_COUNTED, EXPR_IS_MEASURABLE, expression_is_static_only(), FALSE, expression_s::left, esuppl_u::part, PROFILE, PROFILE_END, report_comb_depth, REPORT_DETAILED, REPORT_VERBOSE, expression_s::right, expression_s::suppl, TRUE, and expression_s::ulid.
Referenced by combination_collect(), and combination_display_verbose().
02537 { PROFILE(COMBINATION_OUTPUT_EXPR); 02538 02539 if( (expr != NULL) && (ESUPPL_WAS_COMB_COUNTED( expr->suppl ) == 1) ) { 02540 02541 expr->suppl.part.comb_cntd = 0; 02542 02543 combination_output_expr( expr->right, combination_calc_depth( expr, curr_depth, FALSE ), any_missed, any_measurable, any_excluded, all_excluded ); 02544 combination_output_expr( expr->left, combination_calc_depth( expr, curr_depth, TRUE ), any_missed, any_measurable, any_excluded, all_excluded ); 02545 02546 if( ((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) || 02547 (report_comb_depth == REPORT_VERBOSE) ) { 02548 02549 if( expr->ulid != -1 ) { 02550 *any_missed = 1; 02551 } 02552 if( (EXPR_IS_MEASURABLE( expr ) == 1) && !expression_is_static_only( expr ) ) { 02553 if( ESUPPL_EXCLUDED( expr->suppl ) == 0 ) { 02554 *any_measurable = 1; 02555 if( expr->ulid != -1 ) { 02556 *all_excluded = 0; 02557 } 02558 } else { 02559 *any_excluded = 1; 02560 *all_excluded = 1; 02561 } 02562 } 02563 02564 } 02565 02566 } 02567 02568 PROFILE_END; 02569 02570 }
static 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.
References PROFILE, and PROFILE_END.
Referenced by combination_underline_tree().
00856 { PROFILE(COMBINATION_PARENTHESIZE); 00857 00858 if( parenthesis ) { 00859 00860 /* Create the new code format string with spacing for the parenthesis */ 00861 unsigned int rv = snprintf( *new_code_format, 300, " %s ", pre_code_format ); 00862 assert( rv < 300 ); 00863 00864 /* Update the code format size */ 00865 *code_format_size += 2; 00866 00867 } else { 00868 00869 strcpy( *new_code_format, pre_code_format ); 00870 00871 } 00872 00873 PROFILE_END; 00874 00875 }
static char* combination_prep_line | ( | char * | line, | |
int | start, | |||
int | len | |||
) | [static] |
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.
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 |
References combination_draw_centered_line(), FALSE, free_safe, malloc_safe, PROFILE, PROFILE_END, realloc_safe, strdup_safe, and TRUE.
Referenced by combination_get_expression(), and combination_underline().
01392 { PROFILE(COMBINATION_PREP_LINE); 01393 01394 char* str; /* Prepared line to return */ 01395 char* newstr; /* Prepared line to return */ 01396 int str_size; /* Allocated size of str */ 01397 int exp_id; /* Expression ID of current line */ 01398 int chars_read; /* Number of characters read from sscanf function */ 01399 int i; /* Loop iterator */ 01400 int curr_index; /* Index current character in str to set */ 01401 bool line_ip = FALSE; /* Specifies if a line is currently in progress */ 01402 bool line_seen = FALSE; /* Specifies that a line has been seen for this line */ 01403 int start_ul = 0; /* Index of starting underline */ 01404 01405 /* Allocate memory for string to return */ 01406 str_size = len + 2; 01407 str = (char*)malloc_safe( str_size ); 01408 01409 i = 0; 01410 curr_index = 0; 01411 01412 while( i < (start + len) ) { 01413 01414 if( *(line + i) == '|' ) { 01415 if( i >= start ) { 01416 line_seen = TRUE; 01417 } 01418 if( !line_ip ) { 01419 line_ip = TRUE; 01420 start_ul = i; 01421 if( sscanf( (line + i + 1), "%d%n", &exp_id, &chars_read ) != 1 ) { 01422 assert( 0 == 1 ); 01423 } else { 01424 i += chars_read; 01425 } 01426 } else { 01427 line_ip = FALSE; 01428 if( i >= start ) { 01429 if( start_ul >= start ) { 01430 combination_draw_centered_line( (str + curr_index), ((i - start_ul) + 1), exp_id, TRUE, TRUE ); 01431 curr_index += (i - start_ul) + 1; 01432 } else { 01433 combination_draw_centered_line( (str + curr_index), ((i - start) + 1), exp_id, FALSE, TRUE ); 01434 curr_index += (i - start) + 1; 01435 } 01436 } 01437 } 01438 } else { 01439 if( i >= start ) { 01440 if( *(line + i) == '-' ) { 01441 line_seen = TRUE; 01442 } else { 01443 str[curr_index] = *(line + i); 01444 curr_index++; 01445 } 01446 } 01447 } 01448 01449 i++; 01450 01451 } 01452 01453 if( line_ip ) { 01454 /* If our pointer exceeded the allotted size, resize the str to fit */ 01455 if( i > (start + len) ) { 01456 str = (char*)realloc_safe( str, str_size, (len + 2 + (i - (start + len))) ); 01457 str_size = (len + 2 + (i - (start + len))); 01458 } 01459 if( start_ul >= start ) { 01460 combination_draw_centered_line( (str + curr_index), ((i - start_ul) + 1), exp_id, TRUE, FALSE ); 01461 curr_index += (i - start_ul) + 1; 01462 } else { 01463 combination_draw_centered_line( (str + curr_index), ((i - start) + 1), exp_id, FALSE, FALSE ); 01464 curr_index += (i - start) + 1; 01465 } 01466 } 01467 01468 /* If we didn't see any underlines here, return NULL */ 01469 if( !line_seen ) { 01470 newstr = NULL; 01471 } else { 01472 str[curr_index] = '\0'; 01473 newstr = strdup_safe( str ); 01474 } 01475 01476 /* The str may be a bit oversized, so we copied it and now free it here (where we know its allocated size) */ 01477 free_safe( str, str_size ); 01478 01479 PROFILE_END; 01480 01481 return( newstr ); 01482 01483 }
void combination_report | ( | FILE * | ofile, | |
bool | verbose | |||
) |
Generates report output for combinational logic coverage.
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.
ofile | Pointer to file to output results to | |
verbose | Specifies whether or not to provide verbose information |
References combination_display_funit_summary(), combination_display_instance_summary(), combination_funit_summary(), combination_funit_verbose(), combination_instance_summary(), combination_instance_verbose(), curr_db, FALSE, funit_head, inst_link_s::inst, db_s::inst_head, funit_inst_s::name_diff, inst_link_s::next, PROFILE, PROFILE_END, report_covered, report_exclusions, report_instance, and funit_inst_s::suppl.
Referenced by report_generate().
03051 { PROFILE(COMBINATION_REPORT); 03052 03053 bool missed_found = FALSE; /* If set to TRUE, indicates combinations were missed */ 03054 inst_link* instl; /* Pointer to current instance link */ 03055 int acc_hits = 0; /* Accumulated number of combinations hit */ 03056 int acc_total = 0; /* Accumulated number of combinations in design */ 03057 03058 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 03059 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ COMBINATIONAL LOGIC COVERAGE RESULTS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 03060 fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" ); 03061 03062 if( report_instance ) { 03063 03064 fprintf( ofile, " Logic Combinations\n" ); 03065 fprintf( ofile, "Instance Hit/Miss/Total Percent hit\n" ); 03066 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03067 03068 instl = db_list[curr_db]->inst_head; 03069 while( instl != NULL ) { 03070 missed_found |= combination_instance_summary( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*"), &acc_hits, &acc_total ); 03071 instl = instl->next; 03072 } 03073 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03074 (void)combination_display_instance_summary( ofile, "Accumulated", acc_hits, acc_total ); 03075 03076 if( verbose && (missed_found || report_covered || report_exclusions) ) { 03077 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03078 instl = db_list[curr_db]->inst_head; 03079 while( instl != NULL ) { 03080 combination_instance_verbose( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*") ); 03081 instl = instl->next; 03082 } 03083 } 03084 03085 } else { 03086 03087 fprintf( ofile, " Logic Combinations\n" ); 03088 fprintf( ofile, "Module/Task/Function Filename Hit/Miss/Total Percent hit\n" ); 03089 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03090 03091 missed_found = combination_funit_summary( ofile, db_list[curr_db]->funit_head, &acc_hits, &acc_total ); 03092 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03093 (void)combination_display_funit_summary( ofile, "Accumulated", "", acc_hits, acc_total ); 03094 03095 if( verbose && (missed_found || report_covered || report_exclusions) ) { 03096 fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" ); 03097 combination_funit_verbose( ofile, db_list[curr_db]->funit_head ); 03098 } 03099 03100 } 03101 03102 fprintf( ofile, "\n\n" ); 03103 03104 PROFILE_END; 03105 03106 }
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.
exp | Pointer to expression tree to reset |
References esuppl_u::comb_cntd, combination_reset_counted_expr_tree(), expression_s::left, esuppl_u::part, PROFILE, PROFILE_END, expression_s::right, and expression_s::suppl.
Referenced by combination_reset_counted_expr_tree(), exclude_expr_assign_and_recalc(), and rank_gather_comp_cdd_cov().
00509 { PROFILE(COMBINATION_RESET_COUNTED_EXPR_TREE); 00510 00511 if( exp != NULL ) { 00512 00513 exp->suppl.part.comb_cntd = 0; 00514 00515 combination_reset_counted_expr_tree( exp->left ); 00516 combination_reset_counted_expr_tree( exp->right ); 00517 00518 } 00519 00520 PROFILE_END; 00521 00522 }
static 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.
funit | Pointer to functional unit to reset |
References esuppl_u::comb_cntd, exp_link_s::exp, func_unit_s::exp_head, funit_link_s::funit, funit_is_unnamed(), funit_link_s::next, exp_link_s::next, esuppl_u::part, PROFILE, PROFILE_END, expression_s::suppl, and func_unit_s::tf_head.
Referenced by combination_collect(), combination_funit_verbose(), and combination_instance_verbose().
00475 { PROFILE(COMBINATION_RESET_COUNTED_EXPRS); 00476 00477 exp_link* expl; /* Pointer to current expression list */ 00478 funit_link* child; /* Pointer to current child functional unit */ 00479 00480 assert( funit != NULL ); 00481 00482 /* Reset the comb_cntd bit in all expressions for the current functional unit */ 00483 expl = funit->exp_head; 00484 while( expl != NULL ) { 00485 expl->exp->suppl.part.comb_cntd = 1; 00486 expl = expl->next; 00487 } 00488 00489 /* Do the same for all children functional units that are unnamed */ 00490 child = funit->tf_head; 00491 while( child != NULL ) { 00492 if( funit_is_unnamed( child->funit ) ) { 00493 combination_reset_counted_exprs( child->funit ); 00494 } 00495 child = child->next; 00496 } 00497 00498 PROFILE_END; 00499 00500 }
static 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.
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 |
References AND_COMB, db_gen_exclusion_id(), db_get_exclusion_id_size(), ESUPPL_EXCLUDED, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_01, esuppl_u::eval_10, esuppl_u::eval_11, flag_output_exclusion_ids, gen_char_string(), expression_s::id, exp_info_s::is_comb, expression_s::left, malloc_safe, expression_s::op, exp_info_s::op_str, OR_COMB, esuppl_u::part, PROFILE, PROFILE_END, report_bitwise, expression_s::right, expression_s::suppl, exp_info_s::suppl, expression_s::ulid, expression_s::value, vector_get_eval_a(), vector_get_eval_abc_count(), vector_get_eval_abcd_count(), vector_get_eval_b(), vector_get_eval_c(), vector_get_eval_d(), and vector_s::width.
Referenced by combination_get_missed_expr().
01742 { PROFILE(COMBINATION_TWO_VARS); 01743 01744 int hit; /* Number of combinations hit for this expression */ 01745 int total; /* Total number of combinations for this expression */ 01746 char tmp[20]; /* Temporary string used for calculating line width */ 01747 unsigned int length; /* Specifies the length of the current line */ 01748 char* op = exp_op_info[exp->op].op_str; /* Operation string */ 01749 int lines; /* Specifies the number of lines needed to output this vector */ 01750 unsigned int rv; /* Return value from snprintf calls */ 01751 01752 assert( exp != NULL ); 01753 01754 /* Verify that left child expression is valid for this operation */ 01755 assert( exp->left != NULL ); 01756 01757 /* Verify that right child expression is valid for this operation */ 01758 assert( exp->right != NULL ); 01759 01760 /* Get hit information */ 01761 if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) { 01762 if( report_bitwise && (exp->value->width > 1) ) { 01763 lines = exp->value->width + 2; 01764 total = (3 * exp->value->width); 01765 hit = vector_get_eval_abc_count( exp->value ); 01766 } else { 01767 lines = 1; 01768 total = 3; 01769 hit = ESUPPL_WAS_FALSE( exp->left->suppl ) + ESUPPL_WAS_FALSE( exp->right->suppl ) + exp->suppl.part.eval_11; 01770 } 01771 } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) { 01772 if( report_bitwise && (exp->value->width > 1) ) { 01773 lines = exp->value->width + 2; 01774 total = (3 * exp->value->width); 01775 hit = vector_get_eval_abc_count( exp->value ); 01776 } else { 01777 lines = 1; 01778 total = 3; 01779 hit = ESUPPL_WAS_TRUE( exp->left->suppl ) + ESUPPL_WAS_TRUE( exp->right->suppl ) + exp->suppl.part.eval_00; 01780 } 01781 } else { 01782 if( report_bitwise && (exp->value->width > 1) ) { 01783 lines = exp->value->width + 2; 01784 total = (4 * exp->value->width); 01785 hit = vector_get_eval_abcd_count( exp->value ); 01786 } else { 01787 lines = 1; 01788 total = 4; 01789 hit = exp->suppl.part.eval_00 + 01790 exp->suppl.part.eval_01 + 01791 exp->suppl.part.eval_10 + 01792 exp->suppl.part.eval_11; 01793 } 01794 } 01795 01796 if( ((hit != total) && !ESUPPL_EXCLUDED( exp->suppl )) || 01797 (ESUPPL_EXCLUDED( exp->suppl ) && show_excluded) ) { 01798 01799 char spaces[30]; 01800 unsigned int eid_size; 01801 01802 if( flag_output_exclusion_ids ) { 01803 eid_size = db_get_exclusion_id_size(); 01804 } 01805 01806 spaces[0] = '\0'; 01807 01808 assert( exp->ulid != -1 ); 01809 01810 /* Allocate memory for info array */ 01811 *info_size = 4 + lines; 01812 *info = (char**)malloc_safe( sizeof( char* ) * (*info_size) ); 01813 01814 /* Allocate lines and assign values */ 01815 length = 26; 01816 rv = snprintf( tmp, 20, "%d", exp->ulid ); assert( rv < 20 ); length += strlen( tmp ); 01817 rv = snprintf( tmp, 20, "%d", hit ); assert( rv < 20 ); length += strlen( tmp ); 01818 rv = snprintf( tmp, 20, "%d", total ); assert( rv < 20 ); length += strlen( tmp ); 01819 if( flag_output_exclusion_ids ) { 01820 length += (eid_size - 1) + 4; 01821 gen_char_string( spaces, ' ', ((eid_size - 1) + 4) ); 01822 } 01823 (*info)[0] = (char*)malloc_safe( length ); 01824 if( flag_output_exclusion_ids ) { 01825 rv = snprintf( (*info)[0], length, " (%s) Expression %d (%d/%d)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, total ); 01826 } else { 01827 rv = snprintf( (*info)[0], length, " Expression %d (%d/%d)", exp->ulid, hit, total ); 01828 } 01829 assert( rv < length ); 01830 01831 length = 25 + strlen( op ) + strlen( spaces ); 01832 (*info)[1] = (char*)malloc_safe( length ); 01833 rv = snprintf( (*info)[1], length, "%s ^^^^^^^^^^^^^ - %s", spaces, op ); 01834 assert( rv < length ); 01835 01836 if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) { 01837 01838 if( report_bitwise && (exp->value->width > 1) ) { 01839 01840 unsigned int i; 01841 01842 length = 30 + strlen( spaces ); 01843 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s Bit | LR | LR | LR ", spaces ); assert( rv < length ); 01844 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s ======|=0-=|=-0=|=11=", spaces ); assert( rv < length ); 01845 (*info)[5] = (char*)malloc_safe( length ); rv = snprintf( (*info)[5], length, "%s ------|----|----|----", spaces ); assert( rv < length ); 01846 01847 length = 28 + strlen( spaces ); 01848 (*info)[4] = (char*)malloc_safe( length ); 01849 rv = snprintf( (*info)[4], length, "%s All | %c %c %c", spaces, 01850 (ESUPPL_WAS_FALSE( exp->left->suppl ) ? ' ' : '*'), 01851 (ESUPPL_WAS_FALSE( exp->right->suppl ) ? ' ' : '*'), 01852 ((exp->suppl.part.eval_11 > 0) ? ' ' : '*') ); 01853 assert( rv < length ); 01854 for( i=0; i<exp->value->width; i++ ) { 01855 (*info)[i+6] = (char*)malloc_safe( length ); 01856 rv = snprintf( (*info)[i+6], length, "%s %4u | %c %c %c", spaces, i, 01857 ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'), 01858 ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'), 01859 ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*') ); 01860 assert( rv < length ); 01861 } 01862 01863 } else { 01864 01865 length = 23 + strlen( spaces ); 01866 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s LR | LR | LR ", spaces ); assert( rv < length ); 01867 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s =0-=|=-0=|=11=", spaces ); assert( rv < length ); 01868 01869 length = 21 + strlen( spaces ); 01870 (*info)[4] = (char*)malloc_safe( length ); 01871 rv = snprintf( (*info)[4], length, "%s %c %c %c", spaces, 01872 (ESUPPL_WAS_FALSE( exp->left->suppl ) ? ' ' : '*'), 01873 (ESUPPL_WAS_FALSE( exp->right->suppl ) ? ' ' : '*'), 01874 ((exp->suppl.part.eval_11 > 0) ? ' ' : '*') ); 01875 assert( rv < length ); 01876 01877 } 01878 01879 } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) { 01880 01881 if( report_bitwise && (exp->value->width > 1) ) { 01882 01883 unsigned int i; 01884 01885 length = 30 + strlen( spaces ); 01886 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s Bit | LR | LR | LR ", spaces ); assert( rv < length ); 01887 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s ======|=1-=|=-1=|=00=", spaces ); assert( rv < length ); 01888 (*info)[5] = (char*)malloc_safe( length ); rv = snprintf( (*info)[5], length, "%s ------|----|----|----", spaces ); assert( rv < length ); 01889 01890 length = 28 + strlen( spaces ); 01891 (*info)[4] = (char*)malloc_safe( length ); 01892 rv = snprintf( (*info)[4], length, "%s All | %c %c %c", spaces, 01893 (ESUPPL_WAS_TRUE( exp->left->suppl ) ? ' ' : '*'), 01894 (ESUPPL_WAS_TRUE( exp->right->suppl ) ? ' ' : '*'), 01895 ((exp->suppl.part.eval_00 > 0) ? ' ' : '*') ); 01896 assert( rv < length ); 01897 for( i=0; i<exp->value->width; i++ ) { 01898 (*info)[i+6] = (char*)malloc_safe( length ); 01899 rv = snprintf( (*info)[i+6], length, "%s %4u | %c %c %c", spaces, i, 01900 ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'), 01901 ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'), 01902 ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*') ); 01903 assert( rv < length ); 01904 } 01905 01906 } else { 01907 01908 length = 23 + strlen( spaces ); 01909 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s LR | LR | LR ", spaces ); assert( rv < length ); 01910 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s =1-=|=-1=|=00=", spaces ); assert( rv < length ); 01911 01912 length = 21 + strlen( spaces ); 01913 (*info)[4] = (char*)malloc_safe( length ); 01914 rv = snprintf( (*info)[4], length, "%s %c %c %c", spaces, 01915 (ESUPPL_WAS_TRUE( exp->left->suppl ) ? ' ' : '*'), 01916 (ESUPPL_WAS_TRUE( exp->right->suppl ) ? ' ' : '*'), 01917 ((exp->suppl.part.eval_00 > 0) ? ' ' : '*') ); 01918 assert( rv < length ); 01919 01920 } 01921 01922 } else { 01923 01924 if( report_bitwise && (exp->value->width > 1) ) { 01925 01926 unsigned int i; 01927 01928 length = 35 + strlen( spaces ); 01929 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s Bit | LR | LR | LR | LR ", spaces ); assert( rv < length ); 01930 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s ======|=00=|=01=|=10=|=11=", spaces ); assert( rv < length ); 01931 (*info)[5] = (char*)malloc_safe( length ); rv = snprintf( (*info)[5], length, "%s ------|----|----|----|----", spaces ); assert( rv < length ); 01932 01933 length = 33 + strlen( spaces ); 01934 (*info)[4] = (char*)malloc_safe( length ); 01935 rv = snprintf( (*info)[4], length, "%s All | %c %c %c %c", spaces, 01936 ((exp->suppl.part.eval_00 == 1) ? ' ' : '*'), 01937 ((exp->suppl.part.eval_01 == 1) ? ' ' : '*'), 01938 ((exp->suppl.part.eval_10 == 1) ? ' ' : '*'), 01939 ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') ); 01940 assert( rv < length ); 01941 for( i=0; i<exp->value->width; i++ ) { 01942 (*info)[i+6] = (char*)malloc_safe( length ); 01943 rv = snprintf( (*info)[i+6], length, "%s %4u | %c %c %c %c", spaces, i, 01944 ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'), 01945 ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*'), 01946 ((vector_get_eval_c( exp->value, i ) == 1) ? ' ' : '*'), 01947 ((vector_get_eval_d( exp->value, i ) == 1) ? ' ' : '*') ); 01948 assert( rv < length ); 01949 } 01950 01951 } else { 01952 01953 length = 28 + strlen( spaces ); 01954 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s LR | LR | LR | LR ", spaces ); assert( rv < length ); 01955 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s =00=|=01=|=10=|=11=", spaces ); assert( rv < length ); 01956 01957 length = 26 + strlen( spaces ); 01958 (*info)[4] = (char*)malloc_safe( length ); 01959 rv = snprintf( (*info)[4], length, "%s %c %c %c %c", spaces, 01960 ((exp->suppl.part.eval_00 == 1) ? ' ' : '*'), 01961 ((exp->suppl.part.eval_01 == 1) ? ' ' : '*'), 01962 ((exp->suppl.part.eval_10 == 1) ? ' ' : '*'), 01963 ((exp->suppl.part.eval_11 == 1) ? ' ' : '*') ); 01964 assert( rv < length ); 01965 01966 } 01967 01968 } 01969 01970 } 01971 01972 PROFILE_END; 01973 01974 }
static 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.
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 |
References db_gen_exclusion_id(), db_get_exclusion_id_size(), ESUPPL_EXCLUDED, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, flag_output_exclusion_ids, gen_char_string(), expression_s::id, malloc_safe, expression_s::op, exp_info_s::op_str, PROFILE, PROFILE_END, report_bitwise, expression_s::suppl, expression_s::ulid, expression_s::value, vector_get_eval_a(), vector_get_eval_ab_count(), vector_get_eval_b(), and vector_s::width.
Referenced by combination_get_missed_expr().
01565 { PROFILE(COMBINATION_UNARY); 01566 01567 int hit = 0; /* Number of combinations hit for this expression */ 01568 int tot; /* Total number of coverage points possible */ 01569 char tmp[20]; /* Temporary string used for sizing lines for numbers */ 01570 unsigned int length; /* Length of the current line to allocate */ 01571 char* op = exp_op_info[exp->op].op_str; /* Operations string */ 01572 int lines; /* Specifies the number of lines to allocate memory for */ 01573 unsigned int rv; /* Return value from snprintf calls */ 01574 01575 assert( exp != NULL ); 01576 01577 /* Get hit information */ 01578 if( report_bitwise && (exp->value->width > 1) ) { 01579 hit = vector_get_eval_ab_count( exp->value ); 01580 lines = exp->value->width + 2; 01581 tot = (2 * exp->value->width); 01582 } else { 01583 lines = 1; 01584 tot = 2; 01585 hit = ESUPPL_WAS_FALSE( exp->suppl ) + ESUPPL_WAS_TRUE( exp->suppl ); 01586 } 01587 01588 if( ((hit != tot) && !ESUPPL_EXCLUDED( exp->suppl )) || 01589 (ESUPPL_EXCLUDED( exp->suppl ) && show_excluded) ) { 01590 01591 char spaces[30]; 01592 unsigned int eid_size; 01593 01594 if( flag_output_exclusion_ids ) { 01595 eid_size = db_get_exclusion_id_size(); 01596 } 01597 01598 spaces[0] = '\0'; 01599 01600 assert( exp->ulid != -1 ); 01601 01602 /* Allocate memory for info array */ 01603 *info_size = 4 + lines; 01604 *info = (char**)malloc_safe( sizeof( char* ) * (*info_size) ); 01605 01606 /* Allocate lines and assign values */ 01607 length = 26; 01608 rv = snprintf( tmp, 20, "%d", exp->ulid ); assert( rv < 20 ); length += strlen( tmp ); 01609 rv = snprintf( tmp, 20, "%d", hit ); assert( rv < 20 ); length += strlen( tmp ); 01610 rv = snprintf( tmp, 20, "%d", tot ); assert( rv < 20 ); length += strlen( tmp ); 01611 if( flag_output_exclusion_ids ) { 01612 length += (eid_size - 1) + 4; 01613 gen_char_string( spaces, ' ', ((eid_size - 1) + 4) ); 01614 } 01615 (*info)[0] = (char*)malloc_safe( length ); 01616 if( flag_output_exclusion_ids ) { 01617 rv = snprintf( (*info)[0], length, " (%s) Expression %d (%d/%d)", db_gen_exclusion_id( 'E', exp->id ), exp->ulid, hit, tot ); 01618 } else { 01619 rv = snprintf( (*info)[0], length, " Expression %d (%d/%d)", exp->ulid, hit, tot ); 01620 } 01621 assert( rv < length ); 01622 01623 length = 25 + strlen( op ) + strlen( spaces ); (*info)[1] = (char*)malloc_safe( length ); 01624 rv = snprintf( (*info)[1], length, "%s ^^^^^^^^^^^^^ - %s", spaces, op ); 01625 assert( rv < length ); 01626 01627 if( report_bitwise && (exp->value->width > 1) ) { 01628 01629 char* tmp; 01630 unsigned int i; 01631 01632 length = 23 + strlen( spaces ); 01633 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s Bit | E | E ", spaces ); assert( rv < length ); 01634 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s ======|=0=|=1=", spaces ); assert( rv < length ); 01635 (*info)[5] = (char*)malloc_safe( length ); rv = snprintf( (*info)[5], length, "%s ------|---|---", spaces ); assert( rv < length ); 01636 01637 length = 22 + strlen( spaces ); 01638 (*info)[4] = (char*)malloc_safe( length ); 01639 rv = snprintf( (*info)[4], length, "%s All | %c %c", spaces, 01640 ((ESUPPL_WAS_FALSE( exp->suppl ) == 1) ? ' ' : '*'), 01641 ((ESUPPL_WAS_TRUE( exp->suppl ) == 1) ? ' ' : '*') ); 01642 assert( rv < length ); 01643 for( i=0; i<exp->value->width; i++ ) { 01644 (*info)[i+6] = (char*)malloc_safe( length ); 01645 rv = snprintf( (*info)[i+6], length, "%s %4u | %c %c", spaces, i, 01646 ((vector_get_eval_a( exp->value, i ) == 1) ? ' ' : '*'), 01647 ((vector_get_eval_b( exp->value, i ) == 1) ? ' ' : '*') ); 01648 assert( rv < length ); 01649 } 01650 01651 } else { 01652 01653 length = 16 + strlen( spaces ); 01654 (*info)[2] = (char*)malloc_safe( length ); rv = snprintf( (*info)[2], length, "%s E | E ", spaces ); assert( rv < length ); 01655 (*info)[3] = (char*)malloc_safe( length ); rv = snprintf( (*info)[3], length, "%s =0=|=1=", spaces ); assert( rv < length ); 01656 01657 length = 15 + strlen( spaces ); 01658 (*info)[4] = (char*)malloc_safe( length ); 01659 rv = snprintf( (*info)[4], length, "%s %c %c", spaces, 01660 ((ESUPPL_WAS_FALSE( exp->suppl ) == 1) ? ' ' : '*'), 01661 ((ESUPPL_WAS_TRUE( exp->suppl ) == 1) ? ' ' : '*') ); 01662 assert( rv < length ); 01663 01664 } 01665 01666 } 01667 01668 PROFILE_END; 01669 01670 }
static void combination_underline | ( | FILE * | ofile, | |
char ** | code, | |||
unsigned int | code_depth, | |||
expression * | exp, | |||
func_unit * | funit | |||
) | [static] |
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.
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 |
References combination_prep_line(), combination_underline_tree(), free_safe, expression_s::line, expression_s::op, PROFILE, and PROFILE_END.
Referenced by combination_display_verbose().
01499 { PROFILE(COMBINATION_UNDERLINE); 01500 01501 char** lines; /* Pointer to a stack of lines */ 01502 unsigned int depth; /* Depth of underline stack */ 01503 unsigned int size; /* Width of stack in characters */ 01504 unsigned int i; /* Loop iterator */ 01505 unsigned int j; /* Loop iterator */ 01506 char* tmpstr; /* Temporary string variable */ 01507 unsigned int start = 0; /* Starting index */ 01508 01509 combination_underline_tree( exp, 0, &lines, &depth, &size, exp->op, (code_depth == 1), funit ); 01510 01511 for( j=0; j<code_depth; j++ ) { 01512 01513 assert( code[j] != NULL ); 01514 01515 if( j == 0 ) { 01516 fprintf( ofile, " %7d: %s\n", exp->line, code[j] ); 01517 } else { 01518 fprintf( ofile, " %s\n", code[j] ); 01519 } 01520 01521 if( code_depth == 1 ) { 01522 for( i=0; i<depth; i++ ) { 01523 fprintf( ofile, " %s\n", lines[i] ); 01524 } 01525 } else { 01526 for( i=0; i<depth; i++ ) { 01527 if( (tmpstr = combination_prep_line( lines[i], start, strlen( code[j] ) )) != NULL ) { 01528 fprintf( ofile, " %s\n", tmpstr ); 01529 free_safe( tmpstr, (strlen( tmpstr ) + 1) ); 01530 } 01531 } 01532 } 01533 01534 start += strlen( code[j] ); 01535 01536 free_safe( code[j], (strlen( code[j] ) + 1) ); 01537 01538 } 01539 01540 for( i=0; i<depth; i++ ) { 01541 free_safe( lines[i], (strlen( lines[i] ) + 1) ); 01542 } 01543 01544 if( depth > 0 ) { 01545 free_safe( lines, (sizeof( char* ) * depth) ); 01546 } 01547 01548 if( code_depth > 0 ) { 01549 free_safe( code, (sizeof( char* ) * code_depth) ); 01550 } 01551 01552 PROFILE_END; 01553 01554 }
static 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] |
anonymous | Throw Throw combination_underline_tree combination_underline_tree |
Recursively parses specified expression tree, underlining and labeling each measurable expression.
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 |
References Catch_anonymous, combination_calc_depth(), combination_draw_centered_line(), combination_draw_line(), combination_parenthesize(), vsuppl_u::data_type, DECIMAL, expression_s::elem, ESUPPL_IS_ROOT, ESUPPL_STATIC_BASE, EXP_OP_ADD, EXP_OP_ADD_A, EXP_OP_AEDGE, EXP_OP_ALS_A, EXP_OP_ALSHIFT, EXP_OP_ALWAYS_COMB, EXP_OP_ALWAYS_LATCH, EXP_OP_AND, EXP_OP_AND_A, EXP_OP_ARS_A, EXP_OP_ARSHIFT, EXP_OP_ASSIGN, EXP_OP_BASSIGN, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_CEQ, EXP_OP_CNE, EXP_OP_CONCAT, EXP_OP_COND, EXP_OP_COND_SEL, EXP_OP_DASSIGN, EXP_OP_DELAY, EXP_OP_DIM, EXP_OP_DIV_A, EXP_OP_DIVIDE, EXP_OP_DLY_ASSIGN, EXP_OP_DLY_OP, EXP_OP_EOR, EXP_OP_EQ, EXP_OP_EXPAND, EXP_OP_EXPONENT, EXP_OP_FUNC_CALL, EXP_OP_GE, EXP_OP_GT, EXP_OP_IDEC, EXP_OP_IF, EXP_OP_IINC, EXP_OP_LAND, EXP_OP_LAST, EXP_OP_LE, EXP_OP_LIST, EXP_OP_LOR, EXP_OP_LS_A, EXP_OP_LSHIFT, EXP_OP_LT, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_MLT_A, EXP_OP_MOD, EXP_OP_MOD_A, EXP_OP_MULTIPLY, EXP_OP_NAND, EXP_OP_NASSIGN, EXP_OP_NB_CALL, EXP_OP_NE, EXP_OP_NEDGE, EXP_OP_NEGATE, EXP_OP_NOR, EXP_OP_NXOR, EXP_OP_OR, EXP_OP_OR_A, EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, EXP_OP_PASSIGN, EXP_OP_PDEC, EXP_OP_PEDGE, EXP_OP_PINC, EXP_OP_PLIST, EXP_OP_REPEAT, EXP_OP_RPT_DLY, EXP_OP_RS_A, EXP_OP_RSHIFT, EXP_OP_SASSIGN, EXP_OP_SB2R, EXP_OP_SB2SR, EXP_OP_SBIT_SEL, EXP_OP_SCLOG2, EXP_OP_SI2R, EXP_OP_SIG, EXP_OP_SLIST, EXP_OP_SR2B, EXP_OP_SR2I, EXP_OP_SRANDOM, EXP_OP_SSIGNED, EXP_OP_SSR2B, EXP_OP_SSRANDOM, EXP_OP_STATIC, EXP_OP_STESTARGS, EXP_OP_STIME, EXP_OP_SUB_A, EXP_OP_SUBTRACT, EXP_OP_SUNSIGNED, EXP_OP_SURAND_RANGE, EXP_OP_SURANDOM, EXP_OP_SVALARGS, EXP_OP_TASK_CALL, EXP_OP_TRIGGER, EXP_OP_UAND, EXP_OP_UINV, EXP_OP_UNAND, EXP_OP_UNOR, EXP_OP_UNOT, EXP_OP_UNXOR, EXP_OP_UOR, EXP_OP_UXOR, EXP_OP_WAIT, EXP_OP_WHILE, EXP_OP_XOR, EXP_OP_XOR_A, expr_stmt_u::expr, FALSE, FATAL, free_safe, expression_s::funit, gen_char_string(), expression_s::left, malloc_safe, func_unit_s::name, expression_s::name, expression_s::op, expression_s::parent, esuppl_u::parenthesis, esuppl_u::part, vsuppl_u::part, print_output(), PROFILE, PROFILE_END, QSTRING, vector_s::r32, vector_s::r64, report_comb_depth, REPORT_DETAILED, REPORT_VERBOSE, expression_s::right, scope_extract_back(), scope_gen_printable(), rv32_s::str, rv64_s::str, strdup_safe, expression_s::suppl, vector_s::suppl, Throw, TRUE, Try, expression_s::ulid, user_msg, USER_MSG_LENGTH, vector_s::value, expression_s::value, VDATA_R32, VDATA_R64, vector_to_int(), and vector_to_string().
Referenced by combination_get_expression(), and combination_underline().
00892 { PROFILE(COMBINATION_UNDERLINE_TREE); 00893 00894 char** l_lines; /* Pointer to left underline stack */ 00895 char** r_lines; /* Pointer to right underline stack */ 00896 unsigned int l_depth = 0; /* Index to top of left stack */ 00897 unsigned int r_depth = 0; /* Index to top of right stack */ 00898 unsigned int l_size; /* Number of characters for left expression */ 00899 unsigned int r_size; /* Number of characters for right expression */ 00900 char* exp_sp; /* Space to take place of missing expression(s) */ 00901 char* code_fmt; /* Contains format string for rest of stack */ 00902 char* tmpstr; /* Temporary string value */ 00903 unsigned int comb_missed; /* If set to 1, current combination was missed */ 00904 char* tmpname = NULL; /* Temporary pointer to current signal name */ 00905 char* pname; /* Printable version of signal/function/task name */ 00906 func_unit* tfunit; /* Temporary pointer to found functional unit */ 00907 int ulid; /* Underline ID to use */ 00908 unsigned int rv; /* Return value from snprintf calls */ 00909 00910 *depth = 0; 00911 *size = 0; 00912 l_lines = NULL; 00913 r_lines = NULL; 00914 comb_missed = 0; 00915 code_fmt = (char*)malloc_safe( 300 ); 00916 00917 if( exp != NULL ) { 00918 00919 if( (exp->op == EXP_OP_LAST) || (exp->op == EXP_OP_NB_CALL) ) { 00920 00921 *size = 0; 00922 00923 } else if( exp->op == EXP_OP_STATIC ) { 00924 00925 unsigned int data_type = exp->value->suppl.part.data_type; 00926 00927 if( data_type == VDATA_R64 ) { 00928 00929 *size = strlen( exp->value->value.r64->str ); 00930 00931 } else if( data_type == VDATA_R32 ) { 00932 00933 *size = strlen( exp->value->value.r32->str ); 00934 00935 } else if( ESUPPL_STATIC_BASE( exp->suppl ) == DECIMAL ) { 00936 00937 rv = snprintf( code_fmt, 300, "%d", vector_to_int( exp->value ) ); 00938 assert( rv < 300 ); 00939 *size = strlen( code_fmt ); 00940 00941 /* 00942 If the size of this decimal value is only 1 and its parent is a NEGATE op, 00943 make it two so that we don't have problems with negates and the like later. 00944 */ 00945 if( (*size == 1) && (exp->parent->expr->op == EXP_OP_NEGATE) ) { 00946 *size = 2; 00947 } 00948 00949 } else { 00950 00951 tmpstr = vector_to_string( exp->value, ESUPPL_STATIC_BASE( exp->suppl ), FALSE, 0 ); 00952 *size = strlen( tmpstr ); 00953 free_safe( tmpstr, (strlen( tmpstr ) + 1) ); 00954 00955 /* Adjust for quotation marks */ 00956 if( ESUPPL_STATIC_BASE( exp->suppl ) == QSTRING ) { 00957 *size += 2; 00958 } 00959 00960 } 00961 00962 } else if( exp->op == EXP_OP_SLIST ) { 00963 00964 *size = 2; 00965 strcpy( code_fmt, "@*" ); 00966 00967 } else if( exp->op == EXP_OP_ALWAYS_COMB ) { 00968 00969 *size = 11; 00970 strcpy( code_fmt, "always_comb" ); 00971 00972 } else if( exp->op == EXP_OP_ALWAYS_LATCH ) { 00973 00974 *size = 12; 00975 strcpy( code_fmt, "always_latch" ); 00976 00977 } else if( exp->op == EXP_OP_STIME ) { 00978 00979 *size = 5; 00980 strcpy( code_fmt, "$time" ); 00981 00982 } else if( (exp->op == EXP_OP_SRANDOM) && (exp->left == NULL) ) { 00983 00984 *size = 7; 00985 strcpy( code_fmt, "$random" ); 00986 00987 } else if( (exp->op == EXP_OP_SURANDOM) && (exp->left == NULL) ) { 00988 00989 *size = 8; 00990 strcpy( code_fmt, "$urandom" ); 00991 00992 } else { 00993 00994 Try { 00995 00996 if( (exp->op == EXP_OP_SIG) || (exp->op == EXP_OP_PARAM) ) { 00997 00998 tmpname = scope_gen_printable( exp->name ); 00999 *size = strlen( tmpname ); 01000 switch( *size ) { 01001 case 0 : assert( *size > 0 ); break; 01002 case 1 : *size = 3; strcpy( code_fmt, " %s " ); break; 01003 case 2 : *size = 3; strcpy( code_fmt, " %s" ); break; 01004 default: strcpy( code_fmt, "%s" ); break; 01005 } 01006 01007 free_safe( tmpname, (strlen( tmpname ) + 1) ); 01008 01009 } else { 01010 01011 bool paren = (exp->suppl.part.parenthesis == 1); 01012 01013 combination_underline_tree( exp->left, combination_calc_depth( exp, curr_depth, TRUE ), &l_lines, &l_depth, &l_size, exp->op, center, funit ); 01014 combination_underline_tree( exp->right, combination_calc_depth( exp, curr_depth, FALSE ), &r_lines, &r_depth, &r_size, exp->op, center, funit ); 01015 01016 switch( exp->op ) { 01017 case EXP_OP_XOR : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01018 case EXP_OP_XOR_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01019 case EXP_OP_MULTIPLY : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01020 case EXP_OP_MLT_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01021 case EXP_OP_DIVIDE : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01022 case EXP_OP_DIV_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01023 case EXP_OP_MOD : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01024 case EXP_OP_MOD_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01025 case EXP_OP_ADD : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01026 case EXP_OP_ADD_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01027 case EXP_OP_SUBTRACT : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01028 case EXP_OP_SUB_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01029 case EXP_OP_EXPONENT : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01030 case EXP_OP_AND : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01031 case EXP_OP_AND_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01032 case EXP_OP_OR : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01033 case EXP_OP_OR_A : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01034 case EXP_OP_NAND : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01035 case EXP_OP_NOR : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01036 case EXP_OP_NXOR : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01037 case EXP_OP_LT : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01038 case EXP_OP_GT : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01039 case EXP_OP_LSHIFT : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01040 case EXP_OP_LS_A : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01041 case EXP_OP_ALSHIFT : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01042 case EXP_OP_ALS_A : *size = l_size + r_size + 6; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01043 case EXP_OP_RSHIFT : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01044 case EXP_OP_RS_A : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01045 case EXP_OP_ARSHIFT : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01046 case EXP_OP_ARS_A : *size = l_size + r_size + 6; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01047 case EXP_OP_EQ : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01048 case EXP_OP_CEQ : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01049 case EXP_OP_LE : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01050 case EXP_OP_GE : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01051 case EXP_OP_NE : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01052 case EXP_OP_CNE : *size = l_size + r_size + 5; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01053 case EXP_OP_LOR : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01054 case EXP_OP_LAND : *size = l_size + r_size + 4; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01055 case EXP_OP_COND : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01056 case EXP_OP_COND_SEL : *size = l_size + r_size + 3; combination_parenthesize( paren, "%s %s", &code_fmt, size ); break; 01057 case EXP_OP_UINV : *size = l_size + r_size + 1; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01058 case EXP_OP_UAND : *size = l_size + r_size + 1; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01059 case EXP_OP_UNOT : *size = l_size + r_size + 1; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01060 case EXP_OP_UOR : *size = l_size + r_size + 1; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01061 case EXP_OP_UXOR : *size = l_size + r_size + 1; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01062 case EXP_OP_UNAND : *size = l_size + r_size + 2; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01063 case EXP_OP_UNOR : *size = l_size + r_size + 2; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01064 case EXP_OP_UNXOR : *size = l_size + r_size + 2; combination_parenthesize( paren, " %s", &code_fmt, size ); break; 01065 case EXP_OP_PARAM_SBIT : 01066 case EXP_OP_SBIT_SEL : 01067 if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) && 01068 (exp->parent->expr->op == EXP_OP_DIM) && 01069 (exp->parent->expr->right == exp) ) { 01070 *size = l_size + r_size + 2; 01071 code_fmt[0] = '\0'; 01072 } else { 01073 unsigned int i; 01074 tmpname = scope_gen_printable( exp->name ); 01075 *size = l_size + r_size + strlen( tmpname ) + 2; 01076 for( i=0; i<strlen( tmpname ); i++ ) { 01077 code_fmt[i] = ' '; 01078 } 01079 code_fmt[i] = '\0'; 01080 } 01081 strcat( code_fmt, " %s " ); 01082 free_safe( tmpname, (strlen( tmpname ) + 1) ); 01083 break; 01084 case EXP_OP_PARAM_MBIT : 01085 case EXP_OP_MBIT_SEL : 01086 if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) && 01087 (exp->parent->expr->op == EXP_OP_DIM) && 01088 (exp->parent->expr->right == exp) ) { 01089 *size = l_size + r_size + 3; 01090 code_fmt[0] = '\0'; 01091 } else { 01092 unsigned int i; 01093 tmpname = scope_gen_printable( exp->name ); 01094 *size = l_size + r_size + strlen( tmpname ) + 3; 01095 for( i=0; i<strlen( tmpname ); i++ ) { 01096 code_fmt[i] = ' '; 01097 } 01098 code_fmt[i] = '\0'; 01099 } 01100 strcat( code_fmt, " %s %s " ); 01101 free_safe( tmpname, (strlen( tmpname ) + 1) ); 01102 break; 01103 case EXP_OP_PARAM_MBIT_POS : 01104 case EXP_OP_PARAM_MBIT_NEG : 01105 case EXP_OP_MBIT_POS : 01106 case EXP_OP_MBIT_NEG : 01107 if( (ESUPPL_IS_ROOT( exp->suppl ) == 0) && 01108 (exp->parent->expr->op == EXP_OP_DIM) && 01109 (exp->parent->expr->right == exp) ) { 01110 *size = l_size + r_size + 4; 01111 code_fmt[0] = '\0'; 01112 } else { 01113 unsigned int i; 01114 tmpname = scope_gen_printable( exp->name ); 01115 *size = l_size + r_size + strlen( tmpname ) + 4; 01116 for( i=0; i<strlen( tmpname ); i++ ) { 01117 code_fmt[i] = ' '; 01118 } 01119 code_fmt[i] = '\0'; 01120 } 01121 strcat( code_fmt, " %s %s " ); 01122 free_safe( tmpname, (strlen( tmpname ) + 1) ); 01123 break; 01124 case EXP_OP_TRIGGER : 01125 { 01126 unsigned int i; 01127 tmpname = scope_gen_printable( exp->name ); 01128 *size = l_size + r_size + strlen( tmpname ) + 2; 01129 for( i=0; i<strlen( tmpname ) + 2; i++ ) { 01130 code_fmt[i] = ' '; 01131 } 01132 code_fmt[i] = '\0'; 01133 free_safe( tmpname, (strlen( tmpname ) + 1) ); 01134 } 01135 break; 01136 case EXP_OP_EXPAND : *size = l_size + r_size + 4; strcpy( code_fmt, " %s %s " ); break; 01137 case EXP_OP_CONCAT : *size = l_size + r_size + 2; strcpy( code_fmt, " %s " ); break; 01138 case EXP_OP_PLIST : 01139 case EXP_OP_LIST : *size = l_size + r_size + 2; strcpy( code_fmt, "%s %s" ); break; 01140 case EXP_OP_PEDGE : 01141 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || 01142 (exp->parent->expr->op == EXP_OP_RPT_DLY) || 01143 (exp->parent->expr->op == EXP_OP_DLY_OP) ) { 01144 *size = l_size + r_size + 11; strcpy( code_fmt, " %s " ); 01145 } else { 01146 *size = l_size + r_size + 8; strcpy( code_fmt, " %s" ); 01147 } 01148 break; 01149 case EXP_OP_NEDGE : 01150 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || 01151 (exp->parent->expr->op == EXP_OP_RPT_DLY) || 01152 (exp->parent->expr->op == EXP_OP_DLY_OP) ) { 01153 *size = l_size + r_size + 11; strcpy( code_fmt, " %s " ); 01154 } else { 01155 *size = l_size + r_size + 8; strcpy( code_fmt, " %s" ); 01156 } 01157 break; 01158 case EXP_OP_AEDGE : 01159 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || 01160 (exp->parent->expr->op == EXP_OP_RPT_DLY) || 01161 (exp->parent->expr->op == EXP_OP_DLY_OP) ) { 01162 *size = l_size + r_size + 3; strcpy( code_fmt, " %s " ); 01163 } else { 01164 *size = l_size + r_size + 0; strcpy( code_fmt, "%s" ); 01165 } 01166 break; 01167 case EXP_OP_EOR : 01168 if( (ESUPPL_IS_ROOT( exp->suppl ) == 1) || 01169 (exp->parent->expr->op == EXP_OP_RPT_DLY) || 01170 (exp->parent->expr->op == EXP_OP_DLY_OP) ) { 01171 *size = l_size + r_size + 7; strcpy( code_fmt, " %s %s " ); 01172 } else { 01173 *size = l_size + r_size + 4; strcpy( code_fmt, "%s %s" ); 01174 } 01175 break; 01176 case EXP_OP_CASE : *size = l_size + r_size + 11; strcpy( code_fmt, " %s %s " ); break; 01177 case EXP_OP_CASEX : *size = l_size + r_size + 12; strcpy( code_fmt, " %s %s " ); break; 01178 case EXP_OP_CASEZ : *size = l_size + r_size + 12; strcpy( code_fmt, " %s %s " ); break; 01179 case EXP_OP_DELAY : *size = r_size + 3; strcpy( code_fmt, " %s " ); break; 01180 case EXP_OP_ASSIGN : *size = l_size + r_size + 10; strcpy( code_fmt, " %s %s" ); break; 01181 case EXP_OP_DASSIGN : 01182 case EXP_OP_DLY_ASSIGN : 01183 case EXP_OP_BASSIGN : *size = l_size + r_size + 3; strcpy( code_fmt, "%s %s" ); break; 01184 case EXP_OP_NASSIGN : *size = l_size + r_size + 4; strcpy( code_fmt, "%s %s" ); break; 01185 case EXP_OP_SASSIGN : 01186 case EXP_OP_PASSIGN : *size = r_size; strcpy( code_fmt, "%s" ); break; 01187 case EXP_OP_IF : *size = r_size + 6; strcpy( code_fmt, " %s " ); break; 01188 case EXP_OP_REPEAT : *size = r_size + 10; strcpy( code_fmt, " %s " ); break; 01189 case EXP_OP_WHILE : *size = r_size + 9; strcpy( code_fmt, " %s " ); break; 01190 case EXP_OP_WAIT : *size = r_size + 8; strcpy( code_fmt, " %s " ); break; 01191 case EXP_OP_DLY_OP : 01192 case EXP_OP_RPT_DLY : *size = l_size + r_size + 1; strcpy( code_fmt, "%s %s" ); break; 01193 case EXP_OP_TASK_CALL : 01194 case EXP_OP_FUNC_CALL : 01195 { 01196 unsigned int i; 01197 tfunit = exp->elem.funit; 01198 tmpname = strdup_safe( tfunit->name ); 01199 scope_extract_back( tfunit->name, tmpname, user_msg ); 01200 pname = scope_gen_printable( tmpname ); 01201 *size = l_size + r_size + strlen( pname ) + 4; 01202 for( i=0; i<strlen( pname ); i++ ) { 01203 code_fmt[i] = ' '; 01204 } 01205 code_fmt[i] = '\0'; 01206 strcat( code_fmt, " %s " ); 01207 free_safe( tmpname, (strlen( tfunit->name ) + 1) ); 01208 free_safe( pname, (strlen( pname ) + 1) ); 01209 } 01210 break; 01211 case EXP_OP_NEGATE : *size = l_size + r_size + 1; strcpy( code_fmt, " %s" ); break; 01212 case EXP_OP_DIM : *size = l_size + r_size; strcpy( code_fmt, "%s%s" ); break; 01213 case EXP_OP_IINC : 01214 case EXP_OP_IDEC : *size = l_size + 2; strcpy( code_fmt, " %s" ); break; 01215 case EXP_OP_PINC : 01216 case EXP_OP_PDEC : *size = l_size + 2; strcpy( code_fmt, "%s " ); break; 01217 case EXP_OP_SSIGNED : *size = l_size + 11; strcpy( code_fmt, " %s " ); break; 01218 case EXP_OP_SUNSIGNED : *size = l_size + 13; strcpy( code_fmt, " %s " ); break; 01219 case EXP_OP_SCLOG2 : *size = l_size + 10; strcpy( code_fmt, " %s " ); break; 01220 case EXP_OP_SRANDOM : *size = l_size + 11; strcpy( code_fmt, " %s " ); break; 01221 case EXP_OP_SURANDOM : *size = l_size + 12; strcpy( code_fmt, " %s " ); break; 01222 case EXP_OP_SURAND_RANGE : *size = l_size + 18; strcpy( code_fmt, " %s " ); break; 01223 case EXP_OP_SSRANDOM : *size = l_size + 12; strcpy( code_fmt, " %s " ); break; 01224 case EXP_OP_SR2B : 01225 case EXP_OP_SB2R : *size = l_size + 15; strcpy( code_fmt, " %s " ); break; 01226 case EXP_OP_SI2R : 01227 case EXP_OP_SR2I : *size = l_size + 9; strcpy( code_fmt, " %s " ); break; 01228 case EXP_OP_SSR2B : 01229 case EXP_OP_SB2SR : *size = l_size + 20; strcpy( code_fmt, " %s " ); break; 01230 case EXP_OP_STESTARGS : *size = l_size + 18; strcpy( code_fmt, " %s " ); break; 01231 case EXP_OP_SVALARGS : *size = l_size + 19; strcpy( code_fmt, " %s " ); break; 01232 default : 01233 rv = snprintf( user_msg, USER_MSG_LENGTH, "Internal error: Unknown expression type in combination_underline_tree (%d)", exp->op ); 01234 assert( rv < USER_MSG_LENGTH ); 01235 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01236 Throw 0; 01237 /*@-unreachable@*/ 01238 break; 01239 /*@=unreachable@*/ 01240 01241 } 01242 01243 } 01244 01245 /* Calculate ulid */ 01246 ulid = exp->ulid; 01247 01248 comb_missed = (((report_comb_depth == REPORT_DETAILED) && (curr_depth <= report_comb_depth)) || 01249 (report_comb_depth == REPORT_VERBOSE)) ? ((ulid != -1) ? 1 : 0) : 0; 01250 01251 if( l_depth > r_depth ) { 01252 *depth = l_depth + comb_missed; 01253 } else { 01254 *depth = r_depth + comb_missed; 01255 } 01256 01257 if( *depth > 0 ) { 01258 01259 unsigned int i; 01260 01261 /* Allocate all memory for the stack */ 01262 *lines = (char**)malloc_safe( sizeof( char* ) * (*depth) ); 01263 01264 /* Create underline or space */ 01265 if( comb_missed == 1 ) { 01266 01267 /* Allocate memory for this underline */ 01268 (*lines)[(*depth)-1] = (char*)malloc_safe( *size + 1 ); 01269 01270 if( center ) { 01271 combination_draw_centered_line( (*lines)[(*depth)-1], *size, ulid, TRUE, TRUE ); 01272 } else { 01273 combination_draw_line( (*lines)[(*depth)-1], *size, ulid ); 01274 } 01275 /* printf( "Drawing line (%s), size: %d, depth: %d\n", (*lines)[(*depth)-1], *size, (*depth) ); */ 01276 } 01277 01278 /* Combine the left and right line stacks */ 01279 for( i=0; i<(*depth - comb_missed); i++ ) { 01280 01281 (*lines)[i] = (char*)malloc_safe( *size + 1 ); 01282 01283 if( (i < l_depth) && (i < r_depth) ) { 01284 01285 /* Merge left and right lines */ 01286 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, l_lines[i], r_lines[i] ); 01287 assert( rv < (*size + 1) ); 01288 01289 free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) ); 01290 free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) ); 01291 01292 } else if( i < l_depth ) { 01293 01294 /* Create spaces for right side */ 01295 exp_sp = (char*)malloc_safe( r_size + 1 ); 01296 gen_char_string( exp_sp, ' ', r_size ); 01297 01298 /* Merge left side only */ 01299 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, l_lines[i], exp_sp ); 01300 assert( rv < (*size + 1) ); 01301 01302 free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) ); 01303 free_safe( exp_sp, (r_size + 1) ); 01304 01305 } else if( i < r_depth ) { 01306 01307 if( l_size == 0 ) { 01308 01309 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, r_lines[i] ); 01310 assert( rv < (*size + 1) ); 01311 01312 } else { 01313 01314 /* Create spaces for left side */ 01315 exp_sp = (char*)malloc_safe( l_size + 1 ); 01316 gen_char_string( exp_sp, ' ', l_size ); 01317 01318 /* Merge right side only */ 01319 rv = snprintf( (*lines)[i], (*size + 1), code_fmt, exp_sp, r_lines[i] ); 01320 assert( rv < (*size + 1) ); 01321 01322 free_safe( exp_sp, (l_size + 1) ); 01323 01324 } 01325 01326 free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) ); 01327 01328 } else { 01329 01330 print_output( "Internal error: Reached entry without a left or right underline", FATAL, __FILE__, __LINE__ ); 01331 Throw 0; 01332 01333 } 01334 01335 } 01336 01337 /* Free left child stack */ 01338 if( l_depth > 0 ) { 01339 free_safe( l_lines, (sizeof( char* ) * l_depth) ); 01340 } 01341 01342 /* Free right child stack */ 01343 if( r_depth > 0 ) { 01344 free_safe( r_lines, (sizeof( char* ) * r_depth) ); 01345 } 01346 01347 } 01348 01349 } Catch_anonymous { 01350 unsigned int i; 01351 for( i=0; i<(*depth - comb_missed); i++ ) { 01352 free_safe( (*lines)[i], (strlen( (*lines)[i] ) + 1) ); 01353 } 01354 free_safe( *lines, (sizeof( char* ) * (*depth - comb_missed)) ); 01355 *lines = NULL; 01356 *depth = 0; 01357 for( i=0; i<l_depth; i++ ) { 01358 free_safe( l_lines[i], (strlen( l_lines[i] ) + 1) ); 01359 } 01360 free_safe( l_lines, (sizeof( char* ) * l_depth) ); 01361 for( i=0; i<r_depth; i++ ) { 01362 free_safe( r_lines[i], (strlen( r_lines[i] ) + 1) ); 01363 } 01364 free_safe( r_lines, (sizeof( char* ) * r_depth) ); 01365 Throw 0; 01366 } 01367 01368 } 01369 01370 } 01371 01372 /* Deallocate the code_fmt string */ 01373 free_safe( code_fmt, 300 ); 01374 01375 PROFILE_END; 01376 01377 }
bool allow_multi_expr = TRUE |
Controls whether multi-expressions are used or not.
Referenced by combination_get_tree_stats(), and command_rank().
unsigned int curr_db |
Index of current database in db_list array that is being handled.
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.
Outputs the exclusion ID for an output coverage point. The exclusion ID can be used by the exclude command for excluding/including coverage points.
Referenced by combination_event(), combination_list_missed(), combination_multi_expr_output(), combination_multi_vars(), combination_two_vars(), combination_unary(), fsm_display_arc_verbose(), line_display_verbose(), memory_display_verbose(), ovl_display_verbose(), report_parse_args(), report_print_header(), and toggle_display_verbose().
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.
If set to a boolean value of TRUE, displays all vector combinational logic on a bitwise basis.
Referenced by combination_get_tree_stats(), combination_two_vars(), combination_unary(), and report_parse_args().
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.
Referenced by combination_calc_depth(), combination_get_missed_expr(), combination_get_tree_stats(), combination_output_expr(), combination_underline_tree(), report_generate(), report_parse_args(), and report_print_header().
If set to a boolean value of TRUE, displays covered logic for a particular CDD file. By default, Covered will display uncovered logic. Must be used in conjunction with the -d v|d (verbose output) option.
If set to a boolean value of TRUE, displays excluded coverage points for a particular CDD file. By default, Covered will not display excluded coverage points. This can be useful when used in conjunction with the -x option for including excluded coverage points. Must be used in conjunction with the -d v|d (verbose output) option.
If set to a boolean value of TRUE, provides a coverage information for individual functional unit instances. If set to a value of FALSE, reports coverage information on a functional unit basis, merging results from all instances of same functional unit.
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.