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