#include <stdio.h>
#include "defines.h"
Go to the source code of this file.
Functions | |
| void | combination_reset_counted_expr_tree (expression *exp) |
| Resets combination counted bits in expression tree. | |
| 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_get_stats (func_unit *funit, unsigned int *hit, unsigned int *excluded, unsigned int *total) |
| Calculates combination logic statistics for summary output. | |
| 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_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. | |
| 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. | |
|
||||||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||||||||||||||
|
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 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 }
|
|
||||||||||||
|
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 }
|
1.3.4