#include <stdio.h>
#include <assert.h>
#include "binding.h"
#include "comb.h"
#include "db.h"
#include "defines.h"
#include "expr.h"
#include "fsm.h"
#include "func_iter.h"
#include "func_unit.h"
#include "link.h"
#include "profiler.h"
#include "rank.h"
#include "report.h"
#include "util.h"
#include "vector.h"
#include "vsignal.h"
Functions | |
comp_cdd_cov * | rank_create_comp_cdd_cov (const char *cdd_name, bool required, uint64 timesteps) |
void | rank_dealloc_comp_cdd_cov (comp_cdd_cov *comp_cov) |
static void | rank_usage () |
static bool | rank_parse_args (int argc, int last_arg, const char **argv) |
static void | rank_check_index (unsigned type, uint64 index, int line) |
static void | rank_gather_signal_cov (vsignal *sig, comp_cdd_cov *comp_cov) |
static void | rank_gather_comb_cov (expression *exp, comp_cdd_cov *comp_cov) |
static void | rank_gather_expression_cov (expression *exp, unsigned int exclude, comp_cdd_cov *comp_cov) |
static void | rank_gather_fsm_cov (fsm_table *table, comp_cdd_cov *comp_cov) |
static void | rank_calc_num_cps (funit_inst *inst, uint64 nums[CP_TYPE_NUM]) |
static void | rank_gather_comp_cdd_cov (funit_inst *inst, comp_cdd_cov *comp_cov) |
static void | rank_read_cdd (const char *cdd_name, bool required, bool first, comp_cdd_cov ***comp_cdds, unsigned int *comp_cdd_num) |
static void | rank_selected_cdd_cov (comp_cdd_cov **comp_cdds, unsigned int comp_cdd_num, uint16 *ranked_merged, uint16 *unranked_merged, unsigned int next_cdd, unsigned int selected_cdd) |
static void | rank_perform_weighted_selection (comp_cdd_cov **comp_cdds, unsigned int comp_cdd_num, uint16 *ranked_merged, uint16 *unranked_merged, unsigned int next_cdd, unsigned int *cdds_ranked) |
static void | rank_perform_greedy_sort (comp_cdd_cov **comp_cdds, unsigned int comp_cdd_num, uint16 *ranked_merged, uint64 num_ranked) |
uint64 | rank_count_cps (uint16 *list, unsigned int list_size) |
static void | rank_perform (comp_cdd_cov **comp_cdds, unsigned int comp_cdd_num) |
static void | rank_output (comp_cdd_cov **comp_cdds, unsigned int comp_cdd_num) |
void | command_rank (int argc, int last_arg, const char **argv) |
Parses command-line for rank options and performs rank command. | |
Variables | |
char | user_msg [USER_MSG_LENGTH] |
const exp_info | exp_op_info [EXP_OP_NUM] |
db ** | db_list |
uint64 | num_timesteps |
bool | quiet_mode |
bool | terse_mode |
bool | debug_mode |
int64 | largest_malloc_size |
bool | report_line |
bool | report_toggle |
bool | report_combination |
bool | report_fsm |
bool | report_assertion |
bool | report_memory |
bool | allow_multi_expr |
static str_link * | rank_in_head = NULL |
static str_link * | rank_in_tail = NULL |
static char * | rank_file = NULL |
static uint64 | num_cps [CP_TYPE_NUM] = {0} |
static unsigned int | cdd_type_weight [CP_TYPE_NUM] = {1,1,1,1,1,0} |
static bool | cdd_type_set [CP_TYPE_NUM] = {0} |
static bool | flag_names_only = FALSE |
static unsigned int | cp_depth = 0 |
static unsigned int | longest_name_len = 0 |
static bool | rank_verbose = FALSE |
void command_rank | ( | int | argc, | |
int | last_arg, | |||
const char ** | argv | |||
) |
Parses command-line for rank options and performs rank command.
Performs merge command functionality.
argc | Number of arguments in command-line to parse | |
last_arg | Index of last parsed argument from list | |
argv | List of arguments from command-line to parse |
References allow_multi_expr, Catch_anonymous, COVERED_HEADER, FALSE, free_safe, HEADER, largest_malloc_size, str_link_s::next, NORMAL, print_output(), PROFILE, PROFILE_END, rank_dealloc_comp_cdd_cov(), rank_file, rank_output(), rank_parse_args(), rank_perform(), rank_read_cdd(), rank_verbose, report_assertion, report_combination, report_fsm, report_line, report_memory, report_toggle, str_link_s::str, str_link_delete_list(), str_link_s::suppl, Throw, TRUE, Try, user_msg, and USER_MSG_LENGTH.
Referenced by main().
01733 { PROFILE(COMMAND_RANK); 01734 01735 int i, j; 01736 unsigned int rv; 01737 comp_cdd_cov** comp_cdds = NULL; 01738 unsigned int comp_cdd_num = 0; 01739 bool error = FALSE; 01740 01741 /* Output header information */ 01742 rv = snprintf( user_msg, USER_MSG_LENGTH, COVERED_HEADER ); 01743 assert( rv < USER_MSG_LENGTH ); 01744 print_output( user_msg, HEADER, __FILE__, __LINE__ ); 01745 01746 Try { 01747 01748 unsigned int rv; 01749 bool first = TRUE; 01750 str_link* strl; 01751 timer* atimer = NULL; 01752 01753 /* Parse score command-line */ 01754 if( !rank_parse_args( argc, last_arg, argv ) ) { 01755 01756 /* Make sure that all coverage points are accumulated */ 01757 report_line = TRUE; 01758 report_toggle = TRUE; 01759 report_combination = TRUE; 01760 report_fsm = TRUE; 01761 report_assertion = TRUE; 01762 report_memory = TRUE; 01763 allow_multi_expr = FALSE; 01764 01765 /* Start timer */ 01766 if( rank_verbose ) { 01767 timer_clear( &atimer ); 01768 timer_start( &atimer ); 01769 } 01770 01771 /* Read in databases to merge */ 01772 strl = rank_in_head; 01773 while( strl != NULL ) { 01774 rv = snprintf( user_msg, USER_MSG_LENGTH, "Reading CDD file \"%s\"", strl->str ); 01775 assert( rv < USER_MSG_LENGTH ); 01776 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01777 rv = fflush( stdout ); 01778 assert( rv == 0 ); 01779 rank_read_cdd( strl->str, (strl->suppl == 1), first, &comp_cdds, &comp_cdd_num ); 01780 first = FALSE; 01781 strl = strl->next; 01782 } 01783 01784 if( rank_verbose ) { 01785 timer_stop( &atimer ); 01786 rv = snprintf( user_msg, USER_MSG_LENGTH, "Completed reading in CDD files in %s", timer_to_string( atimer ) ); 01787 assert( rv < USER_MSG_LENGTH ); 01788 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01789 free_safe( atimer, sizeof( timer ) ); 01790 } 01791 01792 /* Peaform the ranking algorithm */ 01793 rank_perform( comp_cdds, comp_cdd_num ); 01794 01795 /* Output the results */ 01796 rank_output( comp_cdds, comp_cdd_num ); 01797 01798 /*@-duplicatequals -formatcode -formattype@*/ 01799 rv = snprintf( user_msg, USER_MSG_LENGTH, "Dynamic memory allocated: %" FMT64 "u bytes", largest_malloc_size ); 01800 assert( rv < USER_MSG_LENGTH ); 01801 /*@=duplicatequals =formatcode =formattype@*/ 01802 print_output( "", NORMAL, __FILE__, __LINE__ ); 01803 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01804 print_output( "", NORMAL, __FILE__, __LINE__ ); 01805 01806 } 01807 01808 } Catch_anonymous { 01809 error = TRUE; 01810 } 01811 01812 /* Deallocate other allocated variables */ 01813 str_link_delete_list( rank_in_head ); 01814 01815 /* Deallocate the compressed CDD coverage structures */ 01816 for( i=0; i<comp_cdd_num; i++ ) { 01817 rank_dealloc_comp_cdd_cov( comp_cdds[i] ); 01818 } 01819 free_safe( comp_cdds, (sizeof( comp_cdd_cov* ) * comp_cdd_num) ); 01820 01821 free_safe( rank_file, (strlen( rank_file ) + 1) ); 01822 01823 if( error ) { 01824 Throw 0; 01825 } 01826 01827 PROFILE_END; 01828 01829 }
static void rank_calc_num_cps | ( | funit_inst * | inst, | |
uint64 | nums[CP_TYPE_NUM] | |||
) | [static] |
Recursively iterates through the instance tree, accumulating values for num_cps array.
inst | Pointer to instance tree to calculate num_cps array | |
nums | Array of coverage point numbers to populate |
References statistic_s::arc_total, statistic_s::assert_total, funit_inst_s::child_head, statistic_s::comb_total, CP_TYPE_ASSERT, CP_TYPE_FSM, CP_TYPE_LINE, CP_TYPE_LOGIC, CP_TYPE_MEM, CP_TYPE_TOGGLE, statistic_s::line_total, statistic_s::mem_ae_total, statistic_s::mem_tog_total, funit_inst_s::next, PROFILE, PROFILE_END, funit_inst_s::stat, statistic_s::state_total, and statistic_s::tog_total.
Referenced by rank_read_cdd().
00973 { PROFILE(RANK_CALC_NUM_CPS); 00974 00975 funit_inst* child; /* Pointer to child instance */ 00976 00977 /* Iterate through children instances */ 00978 child = inst->child_head; 00979 while( child != NULL ) { 00980 rank_calc_num_cps( child, nums ); 00981 child = child->next; 00982 } 00983 00984 /* Add totals to global num_cps array */ 00985 nums[CP_TYPE_LINE] += inst->stat->line_total; 00986 nums[CP_TYPE_TOGGLE] += (inst->stat->tog_total * 2); 00987 nums[CP_TYPE_MEM] += (inst->stat->mem_ae_total * 2) + (inst->stat->mem_tog_total * 2); 00988 nums[CP_TYPE_LOGIC] += inst->stat->comb_total; 00989 if( inst->stat->state_total > 0 ) { 00990 nums[CP_TYPE_FSM] += (unsigned int)inst->stat->state_total; 00991 } 00992 if( inst->stat->arc_total > 0 ) { 00993 nums[CP_TYPE_FSM] += (unsigned int)inst->stat->arc_total; 00994 } 00995 nums[CP_TYPE_ASSERT] += inst->stat->assert_total; 00996 00997 PROFILE_END; 00998 00999 }
static void rank_check_index | ( | unsigned | type, | |
uint64 | index, | |||
int | line | |||
) | [static] |
Checks to make sure that index that will be used exceeds the maximum index (to eliminate memory overruns). Throws exception if the index that will be used violates this check.
type | Type of index that is being checked | |
index | Index value to check | |
line | Line number in source code that hit this error |
References FATAL, num_cps, print_output(), PROFILE, PROFILE_END, Throw, user_msg, and USER_MSG_LENGTH.
Referenced by rank_gather_comb_cov(), rank_gather_expression_cov(), rank_gather_fsm_cov(), and rank_gather_signal_cov().
00671 { PROFILE(RANK_CHECK_INDEX); 00672 00673 if( index >= num_cps[type] ) { 00674 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Last read in CDD file is incompatible with previously read in CDD files. Exiting..." ); 00675 assert( rv < USER_MSG_LENGTH ); 00676 print_output( user_msg, FATAL, __FILE__, line ); 00677 Throw 0; 00678 } 00679 00680 PROFILE_END; 00681 00682 }
uint64 rank_count_cps | ( | uint16 * | list, | |
unsigned int | list_size | |||
) |
list | List of cp counts | |
list_size | Number of elements in the list |
References PROFILE, and PROFILE_END.
Referenced by rank_perform().
01338 { PROFILE(RANK_COUNT_CPS); 01339 01340 uint64 cps = 0; 01341 unsigned int i; 01342 01343 for( i=0; i<list_size; i++ ) { 01344 cps += (list[i] > 0) ? 1 : 0; 01345 } 01346 01347 PROFILE_END; 01348 01349 return( cps ); 01350 01351 }
comp_cdd_cov* rank_create_comp_cdd_cov | ( | const char * | cdd_name, | |
bool | required, | |||
uint64 | timesteps | |||
) |
cdd_name | Name of CDD file that this structure was created from | |
required | Set to TRUE if this CDD is required to be ranked by the user | |
timesteps | Number of simulation timesteps that occurred in the CDD |
References calloc_safe, comp_cdd_cov_s::cdd_name, CP_TYPE_NUM, comp_cdd_cov_s::cps, comp_cdd_cov_s::cps_index, longest_name_len, malloc_safe, num_cps, PROFILE, PROFILE_END, comp_cdd_cov_s::required, strdup_safe, comp_cdd_cov_s::timesteps, comp_cdd_cov_s::total_cps, UL_DIV, and comp_cdd_cov_s::unique_cps.
Referenced by rank_read_cdd().
00173 { PROFILE(RANK_CREATE_COMP_CDD_COV); 00174 00175 comp_cdd_cov* comp_cov; 00176 unsigned int i; 00177 00178 /* Allocate and initialize */ 00179 comp_cov = (comp_cdd_cov*)malloc_safe( sizeof( comp_cdd_cov ) ); 00180 comp_cov->cdd_name = strdup_safe( cdd_name ); 00181 comp_cov->timesteps = timesteps; 00182 comp_cov->total_cps = 0; 00183 comp_cov->unique_cps = 0; 00184 comp_cov->required = required; 00185 00186 /* Save longest name length */ 00187 if( strlen( comp_cov->cdd_name ) > longest_name_len ) { 00188 longest_name_len = strlen( comp_cov->cdd_name ); 00189 } 00190 00191 for( i=0; i<CP_TYPE_NUM; i++ ) { 00192 comp_cov->cps_index[i] = 0; 00193 if( num_cps[i] > 0 ) { 00194 comp_cov->cps[i] = (ulong*)calloc_safe( (UL_DIV(num_cps[i]) + 1), sizeof( ulong ) ); 00195 } else { 00196 comp_cov->cps[i] = NULL; 00197 } 00198 } 00199 00200 PROFILE_END; 00201 00202 return( comp_cov ); 00203 00204 }
void rank_dealloc_comp_cdd_cov | ( | comp_cdd_cov * | comp_cov | ) |
Deallocates the specified compressed CDD coverage structure.
comp_cov | Pointer to compressed CDD coverage structure to deallocate |
References comp_cdd_cov_s::cdd_name, CP_TYPE_NUM, comp_cdd_cov_s::cps, free_safe, num_cps, PROFILE, PROFILE_END, and UL_DIV.
Referenced by command_rank(), and rank_read_cdd().
00211 { PROFILE(RANK_DEALLOC_COMP_CDD_COV); 00212 00213 if( comp_cov != NULL ) { 00214 00215 unsigned int i; 00216 00217 /* Deallocate name */ 00218 free_safe( comp_cov->cdd_name, (strlen( comp_cov->cdd_name ) + 1) ); 00219 00220 /* Deallocate compressed coverage point information */ 00221 for( i=0; i<CP_TYPE_NUM; i++ ) { 00222 free_safe( comp_cov->cps[i], (sizeof( ulong ) * (UL_DIV( num_cps[i] ) + 1)) ); 00223 } 00224 00225 /* Now deallocate ourselves */ 00226 free_safe( comp_cov, sizeof( comp_cdd_cov ) ); 00227 00228 } 00229 00230 PROFILE_END; 00231 00232 }
static void rank_gather_comb_cov | ( | expression * | exp, | |
comp_cdd_cov * | comp_cov | |||
) | [static] |
Recursively iterates through the given expression tree, gathering all combinational logic coverage information and populating the given compressed CDD coverage structure accordingly.
exp | Pointer to current expression to gather combinational logic coverage from | |
comp_cov | Pointer to compressed CDD coverage structure to populate |
References AND_COMB, esuppl_u::comb_cntd, CP_TYPE_LOGIC, comp_cdd_cov_s::cps, comp_cdd_cov_s::cps_index, ESUPPL_WAS_COMB_COUNTED, ESUPPL_WAS_FALSE, ESUPPL_WAS_TRUE, esuppl_u::eval_00, esuppl_u::eval_01, esuppl_u::eval_10, esuppl_u::eval_11, EXPR_IS_COMB, EXPR_IS_EVENT, EXPR_IS_MEASURABLE, expression_is_static_only(), exp_info_s::is_comb, expression_s::left, expression_s::op, OR_COMB, esuppl_u::part, PROFILE, PROFILE_END, rank_check_index(), expression_s::right, exp_info_s::suppl, expression_s::suppl, UL_DIV, and UL_MOD.
Referenced by rank_gather_expression_cov().
00803 { PROFILE(RANK_GATHER_COMB_COV); 00804 00805 if( exp != NULL ) { 00806 00807 /* Gather combination coverage information from children */ 00808 rank_gather_comb_cov( exp->left, comp_cov ); 00809 rank_gather_comb_cov( exp->right, comp_cov ); 00810 00811 /* Calculate combinational logic coverage information */ 00812 if( (EXPR_IS_MEASURABLE( exp ) == 1) && (ESUPPL_WAS_COMB_COUNTED( exp->suppl ) == 0) ) { 00813 00814 /* Calculate current expression combination coverage */ 00815 if( !expression_is_static_only( exp ) ) { 00816 00817 uint64 index; 00818 00819 if( EXPR_IS_COMB( exp ) == 1 ) { 00820 if( exp_op_info[exp->op].suppl.is_comb == AND_COMB ) { 00821 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00822 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00823 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_FALSE( exp->left->suppl ) << UL_MOD(index); 00824 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00825 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00826 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_FALSE( exp->right->suppl ) << UL_MOD(index); 00827 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00828 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00829 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_11 << UL_MOD(index); 00830 } else if( exp_op_info[exp->op].suppl.is_comb == OR_COMB ) { 00831 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00832 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00833 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_TRUE( exp->left->suppl ) << UL_MOD(index); 00834 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00835 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00836 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_TRUE( exp->right->suppl ) << UL_MOD(index); 00837 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00838 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00839 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_00 << UL_MOD(index); 00840 } else { 00841 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00842 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00843 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_00 << UL_MOD(index); 00844 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00845 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00846 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_01 << UL_MOD(index); 00847 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00848 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00849 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_10 << UL_MOD(index); 00850 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00851 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00852 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)exp->suppl.part.eval_11 << UL_MOD(index); 00853 } 00854 } else if( EXPR_IS_EVENT( exp ) == 1 ) { 00855 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00856 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00857 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_TRUE( exp->suppl ) << UL_MOD(index); 00858 } else { 00859 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00860 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00861 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_TRUE( exp->suppl ) << UL_MOD(index); 00862 index = comp_cov->cps_index[CP_TYPE_LOGIC]++; 00863 rank_check_index( CP_TYPE_LOGIC, index, __LINE__ ); 00864 comp_cov->cps[CP_TYPE_LOGIC][UL_DIV(index)] |= (ulong)ESUPPL_WAS_FALSE( exp->suppl ) << UL_MOD(index); 00865 } 00866 00867 } 00868 00869 } 00870 00871 /* Set the counted bit */ 00872 exp->suppl.part.comb_cntd = 1; 00873 00874 } 00875 00876 PROFILE_END; 00877 00878 }
static void rank_gather_comp_cdd_cov | ( | funit_inst * | inst, | |
comp_cdd_cov * | comp_cov | |||
) | [static] |
Gathers all coverage point information from the given functional unit instance and populates the specified compressed CDD coverage structure accordingly.
References funit_inst_s::child_head, combination_reset_counted_expr_tree(), statement_s::exp, FALSE, func_unit_s::fsm_head, func_iter_dealloc(), func_iter_get_next_statement(), func_iter_init(), funit_inst_s::funit, funit_is_unnamed(), funit_inst_s::next, fsm_link_s::next, sig_link_s::next, statement_s::part, PROFILE, PROFILE_END, rank_gather_expression_cov(), rank_gather_fsm_cov(), rank_gather_signal_cov(), sig_link_s::sig, func_unit_s::sig_head, statement_s::suppl, fsm_s::table, fsm_link_s::table, and TRUE.
Referenced by rank_read_cdd().
01008 { PROFILE(RANK_GATHER_COMP_CDD_COV); 01009 01010 sig_link* sigl; /* Pointer to signal link */ 01011 fsm_link* fsml; /* Pointer to FSM link */ 01012 funit_inst* child; /* Pointer to current child instance */ 01013 01014 /* Don't gather information for placeholder instances */ 01015 if( inst->funit != NULL ) { 01016 01017 /* Gather coverage information from expressions */ 01018 if( !funit_is_unnamed( inst->funit ) ) { 01019 func_iter fi; 01020 statement* stmt; 01021 01022 /* First, clear the comb_cntd bits in all of the expressions */ 01023 func_iter_init( &fi, inst->funit, TRUE, FALSE ); 01024 while( (stmt = func_iter_get_next_statement( &fi )) != NULL ) { 01025 combination_reset_counted_expr_tree( stmt->exp ); 01026 } 01027 func_iter_dealloc( &fi ); 01028 01029 /* Then populate the comp_cov structure, accordingly */ 01030 func_iter_init( &fi, inst->funit, TRUE, FALSE ); 01031 while( (stmt = func_iter_get_next_statement( &fi )) != NULL ) { 01032 rank_gather_expression_cov( stmt->exp, stmt->suppl.part.excluded, comp_cov ); 01033 } 01034 func_iter_dealloc( &fi ); 01035 } 01036 01037 /* Gather coverage information from signals */ 01038 sigl = inst->funit->sig_head; 01039 while( sigl != NULL ) { 01040 rank_gather_signal_cov( sigl->sig, comp_cov ); 01041 sigl = sigl->next; 01042 } 01043 01044 /* Gather coverage information from FSMs */ 01045 fsml = inst->funit->fsm_head; 01046 while( fsml != NULL ) { 01047 rank_gather_fsm_cov( fsml->table->table, comp_cov ); 01048 fsml = fsml->next; 01049 } 01050 01051 } 01052 01053 /* Gather coverage information from children */ 01054 child = inst->child_head; 01055 while( child != NULL ) { 01056 rank_gather_comp_cdd_cov( child, comp_cov ); 01057 child = child->next; 01058 } 01059 01060 PROFILE_END; 01061 01062 }
static void rank_gather_expression_cov | ( | expression * | exp, | |
unsigned int | exclude, | |||
comp_cdd_cov * | comp_cov | |||
) | [static] |
Gathers line and combinational logic coverage point information from the given expression and populates the specified compressed CDD coverage structure accordingly.
exp | Pointer to expression to gather coverage information from | |
exclude | Specifies whether line coverage information should be excluded | |
comp_cov | Pointer to compressed CDD coverage structure to populate |
References CP_TYPE_LINE, comp_cdd_cov_s::cps, comp_cdd_cov_s::cps_index, expression_s::exec_num, EXP_OP_CASE, EXP_OP_CASEX, EXP_OP_CASEZ, EXP_OP_DEFAULT, EXP_OP_DELAY, EXP_OP_FORK, EXP_OP_JOIN, EXP_OP_NB_CALL, EXP_OP_NOOP, expression_s::line, expression_s::op, esuppl_u::part, PROFILE, PROFILE_END, rank_check_index(), rank_gather_comb_cov(), esuppl_u::root, expression_s::suppl, UL_DIV, and UL_MOD.
Referenced by rank_gather_comp_cdd_cov().
00888 { PROFILE(RANK_GATHER_EXPRESSION_COV); 00889 00890 /* Calculate line coverage information (NOTE: we currently ignore the excluded status of the line) */ 00891 if( (exp->suppl.part.root == 1) && 00892 (exp->op != EXP_OP_DELAY) && 00893 (exp->op != EXP_OP_CASE) && 00894 (exp->op != EXP_OP_CASEX) && 00895 (exp->op != EXP_OP_CASEZ) && 00896 (exp->op != EXP_OP_DEFAULT) && 00897 (exp->op != EXP_OP_NB_CALL) && 00898 (exp->op != EXP_OP_FORK) && 00899 (exp->op != EXP_OP_JOIN) && 00900 (exp->op != EXP_OP_NOOP) && 00901 (exp->line != 0) ) { 00902 uint64 index = comp_cov->cps_index[CP_TYPE_LINE]++; 00903 rank_check_index( CP_TYPE_LINE, index, __LINE__ ); 00904 if( (exp->exec_num > 0) || exclude ) { 00905 comp_cov->cps[CP_TYPE_LINE][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00906 } 00907 } 00908 00909 /* Calculate combinational logic coverage information */ 00910 rank_gather_comb_cov( exp, comp_cov ); 00911 00912 PROFILE_END; 00913 00914 }
static void rank_gather_fsm_cov | ( | fsm_table * | table, | |
comp_cdd_cov * | comp_cov | |||
) | [static] |
Gathers the FSM coverage points from the given FSM and populates the compressed CDD coverage structure accordingly.
table | Pointer to FSM table to gather coverage information from | |
comp_cov | Pointer to compressed CDD coverage structure to populate |
References fsm_table_s::arcs, CP_TYPE_FSM, comp_cdd_cov_s::cps, comp_cdd_cov_s::cps_index, asuppl_u::excluded, free_safe, fsm_table_arc_s::from, asuppl_u::hit, fsuppl_u::known, malloc_safe, fsm_table_s::num_arcs, fsm_table_s::num_fr_states, asuppl_u::part, fsuppl_u::part, PROFILE, PROFILE_END, rank_check_index(), fsm_table_arc_s::suppl, fsm_table_s::suppl, UL_DIV, and UL_MOD.
Referenced by rank_gather_comp_cdd_cov().
00923 { PROFILE(RANK_GATHER_FSM_COV); 00924 00925 /* We can only create a compressed version of FSM coverage information if it is known */ 00926 if( table->suppl.part.known == 0 ) { 00927 00928 int* state_hits = (int*)malloc_safe( sizeof( int ) * table->num_fr_states ); 00929 unsigned int i; 00930 00931 /* Initialize state_hits array */ 00932 for( i=0; i<table->num_fr_states; i++ ) { 00933 state_hits[i] = 0; 00934 } 00935 00936 /* Iterate through arc transition array and count unique hits */ 00937 for( i=0; i<table->num_arcs; i++ ) { 00938 uint64 index; 00939 if( (table->arcs[i]->suppl.part.hit || table->arcs[i]->suppl.part.excluded) ) { 00940 if( state_hits[table->arcs[i]->from]++ == 0 ) { 00941 index = comp_cov->cps_index[CP_TYPE_FSM]++; 00942 rank_check_index( CP_TYPE_FSM, index, __LINE__ ); 00943 comp_cov->cps[CP_TYPE_FSM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00944 } 00945 index = comp_cov->cps_index[CP_TYPE_FSM]++; 00946 rank_check_index( CP_TYPE_FSM, index, __LINE__ ); 00947 comp_cov->cps[CP_TYPE_FSM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00948 } else { 00949 if( state_hits[table->arcs[i]->from]++ == 0 ) { 00950 index = comp_cov->cps_index[CP_TYPE_FSM]++; 00951 rank_check_index( CP_TYPE_FSM, index, __LINE__ ); 00952 } 00953 index = comp_cov->cps_index[CP_TYPE_FSM]++; 00954 rank_check_index( CP_TYPE_FSM, index, __LINE__ ); 00955 } 00956 } 00957 00958 /* Deallocate state_hits array */ 00959 free_safe( state_hits, (sizeof( int ) * table->num_fr_states) ); 00960 00961 } 00962 00963 PROFILE_END; 00964 00965 }
static void rank_gather_signal_cov | ( | vsignal * | sig, | |
comp_cdd_cov * | comp_cov | |||
) | [static] |
Gathers all coverage point information from the given signal and populates the comp_cov structure accordingly.
sig | Pointer to signal to gather coverage information from | |
comp_cov | Pointer to compressed CDD coverage structure to populate |
References CP_TYPE_MEM, CP_TYPE_TOGGLE, comp_cdd_cov_s::cps, comp_cdd_cov_s::cps_index, vsuppl_u::data_type, vsignal_s::dim, ssuppl_u::excluded, dim_range_s::lsb, ssuppl_u::mba, dim_range_s::msb, vsuppl_u::part, ssuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, rank_check_index(), SSUPPL_TYPE_ENUM, SSUPPL_TYPE_MEM, SSUPPL_TYPE_PARAM, SSUPPL_TYPE_PARAM_REAL, vector_s::suppl, vsignal_s::suppl, ssuppl_u::type, vsignal_s::udim_num, vector_s::ul, UL_DIV, UL_MOD, vector_s::value, vsignal_s::value, VDATA_UL, vector_mem_rw_count(), VTYPE_INDEX_MEM_TOG01, VTYPE_INDEX_MEM_TOG10, VTYPE_INDEX_SIG_TOG01, VTYPE_INDEX_SIG_TOG10, and vector_s::width.
Referenced by rank_gather_comp_cdd_cov().
00690 { PROFILE(RANK_GATHER_SIGNAL_COV); 00691 00692 /* Populate toggle coverage information */ 00693 if( (sig->suppl.part.type != SSUPPL_TYPE_PARAM) && 00694 (sig->suppl.part.type != SSUPPL_TYPE_PARAM_REAL) && 00695 (sig->suppl.part.type != SSUPPL_TYPE_ENUM) && 00696 (sig->suppl.part.type != SSUPPL_TYPE_MEM) && 00697 (sig->suppl.part.mba == 0) ) { 00698 00699 unsigned int i; 00700 if( sig->suppl.part.excluded == 1 ) { 00701 for( i=0; i<sig->value->width; i++ ) { 00702 uint64 index = comp_cov->cps_index[CP_TYPE_TOGGLE]++; 00703 rank_check_index( CP_TYPE_TOGGLE, index, __LINE__ ); 00704 comp_cov->cps[CP_TYPE_TOGGLE][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00705 index = comp_cov->cps_index[CP_TYPE_TOGGLE]++; 00706 rank_check_index( CP_TYPE_TOGGLE, index, __LINE__ ); 00707 comp_cov->cps[CP_TYPE_TOGGLE][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00708 } 00709 } else { 00710 switch( sig->value->suppl.part.data_type ) { 00711 case VDATA_UL : 00712 for( i=0; i<sig->value->width; i++ ) { 00713 uint64 index = comp_cov->cps_index[CP_TYPE_TOGGLE]++; 00714 rank_check_index( CP_TYPE_TOGGLE, index, __LINE__ ); 00715 comp_cov->cps[CP_TYPE_TOGGLE][UL_DIV(index)] |= ((sig->value->value.ul[UL_DIV(i)][VTYPE_INDEX_SIG_TOG01] >> UL_MOD(i)) & (ulong)0x1) << UL_MOD(index); 00716 index = comp_cov->cps_index[CP_TYPE_TOGGLE]++; 00717 rank_check_index( CP_TYPE_TOGGLE, index, __LINE__ ); 00718 comp_cov->cps[CP_TYPE_TOGGLE][UL_DIV(index)] |= ((sig->value->value.ul[UL_DIV(i)][VTYPE_INDEX_SIG_TOG10] >> UL_MOD(i)) & (ulong)0x1) << UL_MOD(index); 00719 } 00720 break; 00721 default : assert( 0 ); break; 00722 } 00723 } 00724 00725 } 00726 00727 /* Populate memory coverage information */ 00728 if( (sig->suppl.part.type == SSUPPL_TYPE_MEM) && (sig->udim_num > 0) ) { 00729 00730 unsigned int i; 00731 unsigned int pwidth = 1; 00732 00733 for( i=(sig->udim_num); i<(sig->udim_num + sig->pdim_num); i++ ) { 00734 if( sig->dim[i].msb > sig->dim[i].lsb ) { 00735 pwidth *= (sig->dim[i].msb - sig->dim[i].lsb) + 1; 00736 } else { 00737 pwidth *= (sig->dim[i].lsb - sig->dim[i].msb) + 1; 00738 } 00739 } 00740 00741 /* Calculate total number of addressable elements and their write/read information */ 00742 for( i=0; i<sig->value->width; i+=pwidth ) { 00743 if( sig->suppl.part.excluded == 1 ) { 00744 uint64 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00745 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00746 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00747 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00748 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00749 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00750 } else { 00751 unsigned int wr = 0; 00752 unsigned int rd = 0; 00753 uint64 index; 00754 vector_mem_rw_count( sig->value, (int)i, (int)((i + pwidth) - 1), &wr, &rd ); 00755 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00756 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00757 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)((wr > 0) ? 1 : 0) << UL_MOD(index); 00758 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00759 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00760 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)((rd > 0) ? 1 : 0) << UL_MOD(index); 00761 } 00762 } 00763 00764 /* Calculate toggle coverage information for the memory */ 00765 if( sig->suppl.part.excluded == 1 ) { 00766 for( i=0; i<sig->value->width; i++ ) { 00767 uint64 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00768 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00769 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00770 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00771 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00772 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= (ulong)0x1 << UL_MOD(index); 00773 } 00774 } else { 00775 switch( sig->value->suppl.part.data_type ) { 00776 case VDATA_UL : 00777 for( i=0; i<sig->value->width; i++ ) { 00778 uint64 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00779 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00780 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= ((sig->value->value.ul[UL_DIV(i)][VTYPE_INDEX_MEM_TOG01] >> UL_MOD(i)) & (ulong)0x1) << UL_MOD(index); 00781 index = comp_cov->cps_index[CP_TYPE_MEM]++; 00782 rank_check_index( CP_TYPE_MEM, index, __LINE__ ); 00783 comp_cov->cps[CP_TYPE_MEM][UL_DIV(index)] |= ((sig->value->value.ul[UL_DIV(i)][VTYPE_INDEX_MEM_TOG10] >> UL_MOD(i)) & (ulong)0x1) << UL_MOD(index); 00784 } 00785 break; 00786 default : assert( 0 ); break; 00787 } 00788 } 00789 00790 } 00791 00792 PROFILE_END; 00793 00794 }
static void rank_output | ( | comp_cdd_cov ** | comp_cdds, | |
unsigned int | comp_cdd_num | |||
) | [static] |
Outputs the ranking of the CDD files to the output file specified from the rank command line.
comp_cdds | Pointer to array of ranked CDD coverage structures | |
comp_cdd_num | Number of allocated structures in comp_cdds array |
References CP_TYPE_NUM, FALSE, FATAL, flag_names_only, free_safe, gen_char_string(), longest_name_len, malloc_safe, NORMAL, num_cps, print_output(), PROFILE, PROFILE_END, rank_file, Throw, comp_cdd_cov_s::timesteps, TRUE, comp_cdd_cov_s::unique_cps, user_msg, and USER_MSG_LENGTH.
Referenced by command_rank().
01569 { PROFILE(RANK_OUTPUT); 01570 01571 FILE* ofile; 01572 unsigned int rv; 01573 01574 if( rank_file == NULL ) { 01575 print_output( "\nGenerating report output to standard output...", NORMAL, __FILE__, __LINE__ ); 01576 } else { 01577 rv = snprintf( user_msg, USER_MSG_LENGTH, "\nGenerating report file \"%s\"...", rank_file ); 01578 assert( rv < USER_MSG_LENGTH ); 01579 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01580 } 01581 01582 if( (ofile = ((rank_file == NULL) ? stdout : fopen( rank_file, "w" ))) != NULL ) { 01583 01584 unsigned int rv; 01585 unsigned int i; 01586 uint64 acc_timesteps = 0; 01587 uint64 acc_unique_cps = 0; 01588 bool unique_found = TRUE; 01589 uint64 total_cps = 0; 01590 01591 /* Calculate the total number of coverage points */ 01592 for( i=0; i<CP_TYPE_NUM; i++ ) { 01593 total_cps += num_cps[i]; 01594 } 01595 01596 /* If we are outputting to standard output, make sure we have a few newlines for readability purposes */ 01597 if( ofile == stdout ) { 01598 fprintf( ofile, "\n\n\n" ); 01599 } 01600 01601 if( flag_names_only ) { 01602 01603 for( i=0; i<comp_cdd_num; i++ ) { 01604 if( comp_cdds[i]->unique_cps > 0 ) { 01605 fprintf( ofile, "%s\n", comp_cdds[i]->cdd_name ); 01606 } 01607 } 01608 01609 } else { 01610 01611 char* str; 01612 char format[100]; 01613 01614 /* Allocate memory for a spacing string */ 01615 str = (char*)malloc_safe( longest_name_len + 1 ); 01616 01617 /* Header information output */ 01618 fprintf( ofile, " ::::::::::::::::::::::::::::::::::::::::::::::::::::\n" ); 01619 fprintf( ofile, " :: ::\n" ); 01620 fprintf( ofile, " :: Covered -- Simulation Ranked Run Order ::\n" ); 01621 fprintf( ofile, " :: ::\n" ); 01622 fprintf( ofile, " ::::::::::::::::::::::::::::::::::::::::::::::::::::\n\n\n" ); 01623 fprintf( ofile, "\n" ); 01624 01625 /* Calculate and display reduction status */ 01626 i = 0; 01627 while( (i<comp_cdd_num) && ((comp_cdds[i]->unique_cps > 0) || comp_cdds[i]->required) ) i++; 01628 if( i == comp_cdd_num ) { 01629 fprintf( ofile, "No reduction occurred\n" ); 01630 } else { 01631 uint64 total_timesteps = 0; 01632 uint64 ranked_timesteps = 0; 01633 unsigned int col1, col2, j; 01634 char str[30]; 01635 char fmt[4096]; 01636 01637 /* Calculated total_timesteps and ranked_timesteps */ 01638 for( j=0; j<comp_cdd_num; j++ ) { 01639 total_timesteps += comp_cdds[j]->timesteps; 01640 if( (comp_cdds[j]->unique_cps > 0) || comp_cdds[j]->required ) { 01641 ranked_timesteps = total_timesteps; 01642 } 01643 } 01644 01645 /* Figure out the largest number for the first column */ 01646 /*@-duplicatequals -formatcode -formattype@*/ 01647 rv = snprintf( str, 30, "%" FMT64 "u", total_timesteps ); col1 = strlen( str ); 01648 assert( rv < 30 ); 01649 rv = snprintf( str, 30, "%" FMT64 "u", ranked_timesteps ); col2 = strlen( str ); 01650 /*@=duplicatequals =formatcode =formattype@*/ 01651 assert( rv < 30 ); 01652 01653 /* Create line for CDD files */ 01654 rv = snprintf( fmt, 4096, "* Reduced %%%uu CDD files down to %%%uu needed to maintain coverage (%%3.0f%%%% reduction, %%5.1fx improvement)\n", col1, col2 ); 01655 assert( rv < 4096 ); 01656 fprintf( ofile, fmt, comp_cdd_num, i, (((comp_cdd_num - i) / (float)comp_cdd_num) * 100), (comp_cdd_num / (float)i) ); 01657 01658 /* Create line for timesteps */ 01659 rv = snprintf( fmt, 4096, "* Reduced %%%ullu timesteps down to %%%ullu needed to maintain coverage (%%3.0f%%%% reduction, %%5.1fx improvement)\n", col1, col2 ); 01660 assert( rv < 4096 ); 01661 fprintf( ofile, fmt, total_timesteps, ranked_timesteps, (((total_timesteps - ranked_timesteps) / (double)total_timesteps) * 100), (total_timesteps / (double)ranked_timesteps) ); 01662 } 01663 fprintf( ofile, "\n" ); 01664 gen_char_string( str, '-', (longest_name_len - 3) ); 01665 fprintf( ofile, "-----------+-------------------------------------------+---------%s------------------------------------------\n", str ); 01666 gen_char_string( str, ' ', (longest_name_len >> 1) ); 01667 fprintf( ofile, " | ACCUMULATIVE | %s CDD\n", str ); 01668 gen_char_string( str, '-', (longest_name_len - 3) ); 01669 fprintf( ofile, "Simulation |-------------------------------------------+---------%s------------------------------------------\n", str ); 01670 gen_char_string( str, ' ', (longest_name_len - 3) ); 01671 fprintf( ofile, "Order | Hit / Total %% Timesteps | R Name%s Hit / Total %% Timesteps\n", str ); 01672 gen_char_string( str, '-', (longest_name_len - 3) ); 01673 fprintf( ofile, "-----------+-------------------------------------------+---------%s------------------------------------------\n", str ); 01674 fprintf( ofile, "\n" ); 01675 01676 /* Calculate a string format */ 01677 rv = snprintf( format, 100, "%%10u %%10llu %%10llu %%3.0f%%%% %%10llu %%c %%-%us %%10llu %%10llu %%3.0f%%%% %%10llu\n", longest_name_len ); 01678 assert( rv < 100 ); 01679 01680 for( i=0; i<comp_cdd_num; i++ ) { 01681 acc_timesteps += comp_cdds[i]->timesteps; 01682 acc_unique_cps += comp_cdds[i]->unique_cps; 01683 if( (comp_cdds[i]->unique_cps == 0) && unique_found && !comp_cdds[i]->required ) { 01684 fprintf( ofile, "\n--------------------------------------- The following CDD files add no additional coverage ----------------------------------------------\n\n" ); 01685 unique_found = FALSE; 01686 } 01687 fprintf( ofile, format, 01688 (i + 1), 01689 acc_unique_cps, 01690 total_cps, 01691 ((acc_unique_cps / (float)total_cps) * 100), 01692 acc_timesteps, 01693 (comp_cdds[i]->required ? '*' : ' '), 01694 comp_cdds[i]->cdd_name, 01695 comp_cdds[i]->total_cps, 01696 total_cps, 01697 ((comp_cdds[i]->total_cps / (float)total_cps) * 100), 01698 comp_cdds[i]->timesteps ); 01699 } 01700 fprintf( ofile, "\n\n" ); 01701 01702 /* Deallocate the spacing string */ 01703 free_safe( str, (longest_name_len + 1) ); 01704 01705 } 01706 01707 /* Close the file if it was opened via fopen */ 01708 if( rank_file != NULL ) { 01709 rv = fclose( ofile ); 01710 assert( rv == 0 ); 01711 } 01712 01713 } else { 01714 01715 rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to open ranking file \"%s\" for writing", rank_file ); 01716 assert( rv < USER_MSG_LENGTH ); 01717 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01718 Throw 0; 01719 01720 } 01721 01722 PROFILE_END; 01723 01724 }
static bool rank_parse_args | ( | int | argc, | |
int | last_arg, | |||
const char ** | argv | |||
) | [static] |
anonymous | Throw Throw Throw |
Parses the score argument list, placing all parsed values into global variables. If an argument is found that is not valid for the rank operation, an error message is displayed to the user.
argc | Number of arguments in argument list argv | |
last_arg | Index of last parsed argument from list | |
argv | Argument list passed to this program |
References Catch_anonymous, cdd_type_set, cdd_type_weight, check_option_value(), cp_depth, CP_TYPE_ASSERT, CP_TYPE_FSM, CP_TYPE_LINE, CP_TYPE_LOGIC, CP_TYPE_MEM, CP_TYPE_TOGGLE, directory_exists(), directory_load(), FALSE, FATAL, file_exists(), flag_names_only, free_safe, is_legal_filename(), str_link_s::next, print_output(), rank_file, rank_usage(), rank_verbose, read_command_file(), str_link_s::str, str_link_add(), str_link_delete_list(), str_link_find(), strdup_safe, str_link_s::suppl, Throw, TRUE, Try, user_msg, USER_MSG_LENGTH, and WARNING.
Referenced by command_rank().
00300 { 00301 00302 int i; 00303 unsigned rank_in_num = 0; 00304 str_link* strl; 00305 str_link* ext_head = NULL; 00306 str_link* ext_tail = NULL; 00307 str_link* dir_head = NULL; 00308 str_link* dir_tail = NULL; 00309 bool help_found = FALSE; 00310 00311 i = last_arg + 1; 00312 00313 while( (i < argc) && !help_found ) { 00314 00315 if( strncmp( "-h", argv[i], 2 ) == 0 ) { 00316 00317 rank_usage(); 00318 help_found = TRUE; 00319 00320 } else if( strncmp( "-o", argv[i], 2 ) == 0 ) { 00321 00322 if( check_option_value( argc, argv, i ) ) { 00323 i++; 00324 if( rank_file != NULL ) { 00325 print_output( "Only one -o option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00326 } else { 00327 if( is_legal_filename( argv[i] ) ) { 00328 rank_file = strdup_safe( argv[i] ); 00329 } else { 00330 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Output file \"%s\" is unwritable", argv[i] ); 00331 assert( rv < USER_MSG_LENGTH ); 00332 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00333 Throw 0; 00334 } 00335 } 00336 } else { 00337 Throw 0; 00338 } 00339 00340 } else if( strncmp( "-f", argv[i], 2 ) == 0 ) { 00341 00342 if( check_option_value( argc, argv, i ) ) { 00343 char** arg_list = NULL; 00344 int arg_num = 0; 00345 unsigned int j; 00346 i++; 00347 Try { 00348 read_command_file( argv[i], &arg_list, &arg_num ); 00349 help_found = rank_parse_args( arg_num, -1, (const char**)arg_list ); 00350 } Catch_anonymous { 00351 for( j=0; j<arg_num; j++ ) { 00352 free_safe( arg_list[j], (strlen( arg_list[j] ) + 1) ); 00353 } 00354 free_safe( arg_list, (sizeof( char* ) * arg_num) ); 00355 Throw 0; 00356 } 00357 for( j=0; j<arg_num; j++ ) { 00358 free_safe( arg_list[j], (strlen( arg_list[j] ) + 1) ); 00359 } 00360 free_safe( arg_list, (sizeof( char* ) * arg_num) ); 00361 } else { 00362 Throw 0; 00363 } 00364 00365 } else if( strncmp( "-required-list", argv[i], 14 ) == 0 ) { 00366 00367 if( check_option_value( argc, argv, i ) ) { 00368 i++; 00369 if( file_exists( argv[i] ) ) { 00370 FILE* file; 00371 if( (file = fopen( argv[i], "r" )) != NULL ) { 00372 char fname[4096]; 00373 unsigned int rv; 00374 while( fscanf( file, "%s", fname ) == 1 ) { 00375 if( file_exists( fname ) ) { 00376 str_link* strl; 00377 if( (strl = str_link_find( fname, rank_in_head )) == NULL ) { 00378 strl = str_link_add( strdup_safe( fname ), &rank_in_head, &rank_in_tail ); 00379 } 00380 strl->suppl = 1; 00381 } else { 00382 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Filename (%s) specified in -required file (%s) does not exist", fname, argv[i] ); 00383 assert( rv < USER_MSG_LENGTH ); 00384 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00385 Throw 0; 00386 } 00387 } 00388 rv = fclose( file ); 00389 assert( rv == 0 ); 00390 } else { 00391 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to read -required-list file (%s)", argv[i] ); 00392 assert( rv < USER_MSG_LENGTH ); 00393 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00394 Throw 0; 00395 } 00396 } else { 00397 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Filename specified for -required-list option (%s) does not exist", argv[i] ); 00398 assert( rv < USER_MSG_LENGTH ); 00399 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00400 Throw 0; 00401 } 00402 00403 } else { 00404 Throw 0; 00405 } 00406 00407 } else if( strncmp( "-required-cdd", argv[i], 13 ) == 0 ) { 00408 00409 if( check_option_value( argc, argv, i ) ) { 00410 i++; 00411 if( file_exists( argv[i] ) ) { 00412 str_link* strl; 00413 if( (strl = str_link_find( argv[i], rank_in_head )) == NULL ) { 00414 strl = str_link_add( strdup_safe( argv[i] ), &rank_in_head, &rank_in_tail ); 00415 } 00416 strl->suppl = 1; 00417 } else { 00418 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to read -required-cdd file (%s)", argv[i] ); 00419 assert( rv < USER_MSG_LENGTH ); 00420 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00421 Throw 0; 00422 } 00423 } else { 00424 Throw 0; 00425 } 00426 00427 } else if( strncmp( "-ext", argv[i], 4 ) == 0 ) { 00428 00429 if( check_option_value( argc, argv, i ) ) { 00430 i++; 00431 (void)str_link_add( strdup_safe( argv[i] ), &ext_head, &ext_tail ); 00432 } else { 00433 Throw 0; 00434 } 00435 00436 } else if( strncmp( "-weight-line", argv[i], 12 ) == 0 ) { 00437 00438 if( check_option_value( argc, argv, i ) ) { 00439 i++; 00440 if( cdd_type_set[CP_TYPE_LINE] ) { 00441 print_output( "Only one -weight-line option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00442 } else { 00443 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_LINE] ) != 1 ) { 00444 print_output( "Value specified after -weight-line must be a number", FATAL, __FILE__, __LINE__ ); 00445 Throw 0; 00446 } else { 00447 cdd_type_set[CP_TYPE_LINE] = TRUE; 00448 } 00449 } 00450 } else { 00451 Throw 0; 00452 } 00453 00454 } else if( strncmp( "-weight-toggle", argv[i], 14 ) == 0 ) { 00455 00456 if( check_option_value( argc, argv, i ) ) { 00457 i++; 00458 if( cdd_type_set[CP_TYPE_TOGGLE] ) { 00459 print_output( "Only one -weight-toggle option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00460 } else { 00461 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_TOGGLE] ) != 1 ) { 00462 print_output( "Value specified after -weight-toggle must be a number", FATAL, __FILE__, __LINE__ ); 00463 Throw 0; 00464 } else { 00465 cdd_type_set[CP_TYPE_TOGGLE] = TRUE; 00466 } 00467 } 00468 } else { 00469 Throw 0; 00470 } 00471 00472 } else if( strncmp( "-weight-memory", argv[i], 14 ) == 0 ) { 00473 00474 if( check_option_value( argc, argv, i ) ) { 00475 i++; 00476 if( cdd_type_set[CP_TYPE_MEM] ) { 00477 print_output( "Only one -weight-memory option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00478 } else { 00479 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_MEM] ) != 1 ) { 00480 print_output( "Value specified after -weight-memory must be a number", FATAL, __FILE__, __LINE__ ); 00481 Throw 0; 00482 } else { 00483 cdd_type_set[CP_TYPE_MEM] = TRUE; 00484 } 00485 } 00486 } else { 00487 Throw 0; 00488 } 00489 00490 } else if( strncmp( "-weight-comb", argv[i], 12 ) == 0 ) { 00491 00492 if( check_option_value( argc, argv, i ) ) { 00493 i++; 00494 if( cdd_type_set[CP_TYPE_LOGIC] ) { 00495 print_output( "Only one -weight-comb option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00496 } else { 00497 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_LOGIC] ) != 1 ) { 00498 print_output( "Value specified after -weight-comb must be a number", FATAL, __FILE__, __LINE__ ); 00499 Throw 0; 00500 } else { 00501 cdd_type_set[CP_TYPE_LOGIC] = TRUE; 00502 } 00503 } 00504 } else { 00505 Throw 0; 00506 } 00507 00508 } else if( strncmp( "-weight-fsm", argv[i], 11 ) == 0 ) { 00509 00510 if( check_option_value( argc, argv, i ) ) { 00511 i++; 00512 if( cdd_type_set[CP_TYPE_FSM] ) { 00513 print_output( "Only one -weight-fsm option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00514 } else { 00515 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_FSM] ) != 1 ) { 00516 print_output( "Value specified after -weight-fsm must be a number", FATAL, __FILE__, __LINE__ ); 00517 Throw 0; 00518 } else { 00519 cdd_type_set[CP_TYPE_FSM] = TRUE; 00520 } 00521 } 00522 } else { 00523 Throw 0; 00524 } 00525 00526 } else if( strncmp( "-weight-assert", argv[i], 14 ) == 0 ) { 00527 00528 if( check_option_value( argc, argv, i ) ) { 00529 i++; 00530 if( cdd_type_set[CP_TYPE_ASSERT] ) { 00531 print_output( "Only one -weight-assert option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00532 } else { 00533 if( sscanf( argv[i], "%u", &cdd_type_weight[CP_TYPE_ASSERT] ) != 1 ) { 00534 print_output( "Value specified after -weight-assert must be a number", FATAL, __FILE__, __LINE__ ); 00535 Throw 0; 00536 } else { 00537 cdd_type_set[CP_TYPE_ASSERT] = TRUE; 00538 } 00539 } 00540 } else { 00541 Throw 0; 00542 } 00543 00544 } else if( strncmp( "-names-only", argv[i], 11 ) == 0 ) { 00545 00546 flag_names_only = TRUE; 00547 00548 } else if( strncmp( "-depth", argv[i], 6 ) == 0 ) { 00549 00550 if( check_option_value( argc, argv, i ) ) { 00551 i++; 00552 if( cp_depth != 0 ) { 00553 print_output( "Only one -depth option is allowed on the rank command-line. Using first value...", WARNING, __FILE__, __LINE__ ); 00554 } else { 00555 if( (sscanf( argv[i], "%u", &cp_depth ) != 1) || (cp_depth == 0) ) { 00556 print_output( "Value specified after -depth must be a positive, non-zero number", FATAL, __FILE__, __LINE__ ); 00557 Throw 0; 00558 } 00559 } 00560 } else { 00561 Throw 0; 00562 } 00563 00564 } else if( strncmp( "-d", argv[i], 2 ) == 0 ) { 00565 00566 if( check_option_value( argc, argv, i ) ) { 00567 i++; 00568 if( directory_exists( argv[i] ) ) { 00569 (void)str_link_add( strdup_safe( argv[i] ), &dir_head, &dir_tail ); 00570 } else { 00571 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Specified -d directory (%s) does not exist", argv[i] ); 00572 assert( rv < USER_MSG_LENGTH ); 00573 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00574 Throw 0; 00575 } 00576 } else { 00577 Throw 0; 00578 } 00579 00580 } else if( strncmp( "-v", argv[i], 2 ) == 0 ) { 00581 00582 rank_verbose = TRUE; 00583 00584 } else if( strncmp( "-", argv[i], 1 ) == 0 ) { 00585 00586 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unknown rank option (%s) specified.", argv[i] ); 00587 assert( rv < USER_MSG_LENGTH ); 00588 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00589 Throw 0; 00590 00591 } else { 00592 00593 /* The name of a file to rank */ 00594 if( file_exists( argv[i] ) ) { 00595 00596 if( str_link_find( argv[i], rank_in_head ) == NULL ) { 00597 00598 /* Add the specified rank file to the list */ 00599 (void)str_link_add( strdup_safe( argv[i] ), &rank_in_head, &rank_in_tail ); 00600 00601 } 00602 00603 } else { 00604 00605 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "CDD file (%s) does not exist", argv[i] ); 00606 assert( rv < USER_MSG_LENGTH ); 00607 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00608 Throw 0; 00609 00610 } 00611 00612 } 00613 00614 i++; 00615 00616 } 00617 00618 if( !help_found ) { 00619 00620 Try { 00621 00622 /* Load any ranking files found in specified directories */ 00623 strl = dir_head; 00624 while( strl != NULL ) { 00625 directory_load( strl->str, ext_head, &rank_in_head, &rank_in_tail ); 00626 strl = strl->next; 00627 } 00628 00629 } Catch_anonymous { 00630 str_link_delete_list( ext_head ); 00631 str_link_delete_list( dir_head ); 00632 Throw 0; 00633 } 00634 00635 /* Count the number of files being ranked */ 00636 strl = rank_in_head; 00637 while( strl != NULL ) { 00638 rank_in_num++; 00639 strl = strl->next; 00640 } 00641 00642 /* Check to make sure that the user specified at least two files to rank */ 00643 if( rank_in_num < 2 ) { 00644 print_output( "Must specify at least two CDD files to rank", FATAL, __FILE__, __LINE__ ); 00645 Throw 0; 00646 } 00647 00648 /* If no -depth option was specified, set its value to 1 */ 00649 if( cp_depth == 0 ) { 00650 cp_depth = 1; 00651 } 00652 00653 } 00654 00655 /* Deallocate the temporary lists */ 00656 str_link_delete_list( ext_head ); 00657 str_link_delete_list( dir_head ); 00658 00659 return( help_found ); 00660 00661 }
static void rank_perform | ( | comp_cdd_cov ** | comp_cdds, | |
unsigned int | comp_cdd_num | |||
) | [static] |
Performs the task of ranking the CDD files and rearranging them in the comp_cdds array such that the first CDD file is located at index 0.
comp_cdds | Pointer to array of compressed CDD coverage structures to rank | |
comp_cdd_num | Number of allocated structures in comp_cdds array |
References calloc_safe, CP_TYPE_ASSERT, CP_TYPE_FSM, CP_TYPE_LINE, CP_TYPE_LOGIC, CP_TYPE_MEM, CP_TYPE_NUM, CP_TYPE_TOGGLE, debug_mode, free_safe, malloc_safe_nolimit, NORMAL, num_cps, print_output(), PROFILE, PROFILE_END, quiet_mode, rank_count_cps(), rank_perform_greedy_sort(), rank_perform_weighted_selection(), rank_selected_cdd_cov(), rank_verbose, terse_mode, comp_cdd_cov_s::total_cps, UL_DIV, UL_MOD, comp_cdd_cov_s::unique_cps, user_msg, and USER_MSG_LENGTH.
Referenced by command_rank().
01360 { PROFILE(RANK_PERFORM); 01361 01362 unsigned int i, j, k; 01363 uint16* ranked_merged; 01364 uint16* unranked_merged; 01365 uint16 merged_index = 0; 01366 uint64 total = 0; 01367 uint64 total_hitable; 01368 unsigned int next_cdd = 0; 01369 unsigned int most_unique; 01370 unsigned int count; 01371 unsigned int cdds_ranked = 0; 01372 timer* atimer = NULL; 01373 unsigned int rv; 01374 01375 if( ((!quiet_mode && !terse_mode) || debug_mode) && !rank_verbose ) { 01376 printf( "Ranking CDD files " ); 01377 rv = fflush( stdout ); 01378 assert( rv == 0 ); 01379 } 01380 01381 /* Calculate the total number of needed merged entries to store accumulated information */ 01382 for( i=0; i<CP_TYPE_NUM; i++ ) { 01383 total += num_cps[i]; 01384 } 01385 assert( total > 0 ); 01386 01387 /* Allocate merged array */ 01388 ranked_merged = (uint16*)calloc_safe( total, sizeof( uint16 ) ); 01389 unranked_merged = (uint16*)malloc_safe_nolimit( sizeof( uint16 ) * total ); 01390 01391 if( rank_verbose ) { 01392 /*@-duplicatequals -formatcode -formattype@*/ 01393 rv = snprintf( user_msg, USER_MSG_LENGTH, "\nRanking %u CDD files with %" FMT64 "u coverage points (%" FMT64 "u line, %" FMT64 "u toggle, %" FMT64 "u memory, %" FMT64 "u logic, %" FMT64 "u FSM, %" FMT64 "u assertion)", 01394 comp_cdd_num, total, num_cps[CP_TYPE_LINE], num_cps[CP_TYPE_TOGGLE], num_cps[CP_TYPE_MEM], num_cps[CP_TYPE_LOGIC], num_cps[CP_TYPE_FSM], num_cps[CP_TYPE_ASSERT] ); 01395 /*@=duplicatequals =formatcode =formattype@*/ 01396 assert( rv < USER_MSG_LENGTH ); 01397 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01398 } 01399 01400 /* Step 1 - Initialize merged results array, calculate uniqueness and total values of each compressed CDD coverage structure */ 01401 for( i=0; i<CP_TYPE_NUM; i++ ) { 01402 for( j=0; j<num_cps[i]; j++ ) { 01403 uint16 bit_total = 0; 01404 unsigned int set_cdd; 01405 for( k=0; k<comp_cdd_num; k++ ) { 01406 if( (comp_cdds[k]->cps[i][UL_DIV(j)] & ((ulong)0x1 << UL_MOD(j))) != 0 ) { 01407 comp_cdds[k]->total_cps++; 01408 set_cdd = k; 01409 bit_total++; 01410 } 01411 } 01412 unranked_merged[merged_index++] = bit_total; 01413 01414 /* If we found exactly one CDD file that hit this coverage point, mark it in the corresponding CDD file */ 01415 if( bit_total == 1 ) { 01416 comp_cdds[set_cdd]->unique_cps++; 01417 } 01418 } 01419 } 01420 01421 if( rank_verbose ) { 01422 total_hitable = rank_count_cps( unranked_merged, total ); 01423 /*@-duplicatequals -formatcode +ignorequals@*/ 01424 rv = snprintf( user_msg, USER_MSG_LENGTH, "Ignoring %" FMT64 "u coverage points that were not hit by any CDD file", (total - total_hitable) ); 01425 /*@=duplicatequals =formatcode =ignorequals@*/ 01426 assert( rv < USER_MSG_LENGTH ); 01427 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01428 01429 print_output( "\nPhase 1: Adding user-required files", NORMAL, __FILE__, __LINE__ ); 01430 rv = fflush( stdout ); 01431 assert( rv == 0 ); 01432 timer_clear( &atimer ); 01433 timer_start( &atimer ); 01434 } 01435 01436 /* Step 2 - Immediately rank all of the required CDDs */ 01437 for( i=0; i<comp_cdd_num; i++ ) { 01438 if( comp_cdds[i]->required ) { 01439 rank_selected_cdd_cov( comp_cdds, comp_cdd_num, ranked_merged, unranked_merged, next_cdd, i ); 01440 next_cdd++; 01441 } 01442 } 01443 01444 if( rank_verbose ) { 01445 uint64 ranked_cps = rank_count_cps( ranked_merged, total ); 01446 timer_stop( &atimer ); 01447 rv = snprintf( user_msg, USER_MSG_LENGTH, " Ranked %u CDD files (Total ranked: %u, Remaining: %u)", next_cdd, next_cdd, (comp_cdd_num - next_cdd) ); 01448 assert( rv < USER_MSG_LENGTH ); 01449 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01450 /*@-duplicatequals -formatcode -formattype@*/ 01451 rv = snprintf( user_msg, USER_MSG_LENGTH, " %" FMT64 "u points covered, %" FMT64 "u points remaining", ranked_cps, (total_hitable - ranked_cps) ); 01452 /*@=duplicatequals =formatcode =formattype@*/ 01453 assert( rv < USER_MSG_LENGTH ); 01454 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01455 rv = snprintf( user_msg, USER_MSG_LENGTH, "Completed phase 1 in %s", timer_to_string( atimer ) ); 01456 assert( rv < USER_MSG_LENGTH ); 01457 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01458 01459 count = next_cdd; 01460 print_output( "\nPhase 2: Adding files that hit unique coverage points", NORMAL, __FILE__, __LINE__ ); 01461 rv = fflush( stdout ); 01462 assert( rv == 0 ); 01463 timer_clear( &atimer ); 01464 timer_start( &atimer ); 01465 } 01466 01467 /* Step 3 - Start with the most unique CDDs */ 01468 do { 01469 most_unique = next_cdd; 01470 for( i=(next_cdd+1); i<comp_cdd_num; i++ ) { 01471 if( comp_cdds[i]->unique_cps > comp_cdds[most_unique]->unique_cps ) { 01472 most_unique = i; 01473 } 01474 } 01475 if( comp_cdds[most_unique]->unique_cps > 0 ) { 01476 rank_selected_cdd_cov( comp_cdds, comp_cdd_num, ranked_merged, unranked_merged, next_cdd, most_unique ); 01477 next_cdd++; 01478 } 01479 } while( (next_cdd < comp_cdd_num) && (comp_cdds[most_unique]->unique_cps > 0) ); 01480 01481 if( rank_verbose ) { 01482 uint64 ranked_cps = rank_count_cps( ranked_merged, total ); 01483 timer_stop( &atimer ); 01484 rv = snprintf( user_msg, USER_MSG_LENGTH, " Ranked %u CDD files (Total ranked: %u, Remaining: %u)", (next_cdd - count), next_cdd, (comp_cdd_num - next_cdd) ); 01485 assert( rv < USER_MSG_LENGTH ); 01486 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01487 /*@-duplicatequals -formatcode -formattype@*/ 01488 rv = snprintf( user_msg, USER_MSG_LENGTH, " %" FMT64 "u points covered, %" FMT64 "u points remaining", ranked_cps, (total_hitable - ranked_cps) ); 01489 /*@=duplicatequals =formatcode =formattype@*/ 01490 assert( rv < USER_MSG_LENGTH ); 01491 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01492 rv = snprintf( user_msg, USER_MSG_LENGTH, "Completed phase 2 in %s", timer_to_string( atimer ) ); 01493 assert( rv < USER_MSG_LENGTH ); 01494 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01495 01496 count = next_cdd; 01497 print_output( "\nPhase 3: Adding files that hit remaining coverage points and eliminating redundant files", NORMAL, __FILE__, __LINE__ ); 01498 rv = fflush( stdout ); 01499 assert( rv == 0 ); 01500 timer_clear( &atimer ); 01501 timer_start( &atimer ); 01502 } 01503 01504 /* Step 4 - Select coverage based on user-specified factors */ 01505 if( next_cdd < comp_cdd_num ) { 01506 rank_perform_weighted_selection( comp_cdds, comp_cdd_num, ranked_merged, unranked_merged, next_cdd, &cdds_ranked ); 01507 } 01508 01509 if( rank_verbose ) { 01510 uint64 ranked_cps = rank_count_cps( ranked_merged, total ); 01511 timer_stop( &atimer ); 01512 rv = snprintf( user_msg, USER_MSG_LENGTH, " Ranked %u CDD files (Total ranked: %u, Eliminated: %u)", cdds_ranked, (count + cdds_ranked), (comp_cdd_num - (count + cdds_ranked)) ); 01513 assert( rv < USER_MSG_LENGTH ); 01514 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01515 /*@-duplicatequals -formatcode -formattype@*/ 01516 rv = snprintf( user_msg, USER_MSG_LENGTH, " %" FMT64 "u points covered, %" FMT64 "u points remaining", ranked_cps, (total_hitable - ranked_cps) ); 01517 /*@=duplicatequals =formatcode =formattype@*/ 01518 assert( rv < USER_MSG_LENGTH ); 01519 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01520 rv = snprintf( user_msg, USER_MSG_LENGTH, "Completed phase 3 in %s", timer_to_string( atimer ) ); 01521 assert( rv < USER_MSG_LENGTH ); 01522 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01523 01524 print_output( "\nPhase 4: Sorting CDD files selected for ranking (no reductions)", NORMAL, __FILE__, __LINE__ ); 01525 rv = fflush( stdout ); 01526 assert( rv == 0 ); 01527 timer_clear( &atimer ); 01528 timer_start( &atimer ); 01529 } 01530 01531 /* Step 5 - Re-sort the list using a greedy algorithm */ 01532 rank_perform_greedy_sort( comp_cdds, comp_cdd_num, ranked_merged, total ); 01533 01534 if( rank_verbose ) { 01535 timer_stop( &atimer ); 01536 rv = snprintf( user_msg, USER_MSG_LENGTH, "Completed phase 4 in %s", timer_to_string( atimer ) ); 01537 assert( rv < USER_MSG_LENGTH ); 01538 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01539 rv = fflush( stdout ); 01540 assert( rv == 0 ); 01541 free_safe( atimer, sizeof( timer ) ); 01542 01543 if( comp_cdd_num == (count + cdds_ranked) ) { 01544 rv = snprintf( user_msg, USER_MSG_LENGTH, "\nSUMMARY: No reduction occurred. %u needed/required", (count + cdds_ranked) ); 01545 assert( rv < USER_MSG_LENGTH ); 01546 } else { 01547 rv = snprintf( user_msg, USER_MSG_LENGTH, "\nSUMMARY: Reduced %u CDD files down to %u needed/required", comp_cdd_num, (count + cdds_ranked) ); 01548 assert( rv < USER_MSG_LENGTH ); 01549 } 01550 print_output( user_msg, NORMAL, __FILE__, __LINE__ ); 01551 } 01552 01553 /* Deallocate merged CDD coverage structure */ 01554 free_safe( ranked_merged, (sizeof( uint16 ) * total ) ); 01555 free_safe( unranked_merged, (sizeof( uint16 ) * total ) ); 01556 01557 PROFILE_END; 01558 01559 }
static void rank_perform_greedy_sort | ( | comp_cdd_cov ** | comp_cdds, | |
unsigned int | comp_cdd_num, | |||
uint16 * | ranked_merged, | |||
uint64 | num_ranked | |||
) | [static] |
Re-sorts the compressed CDD coverage array to order them based on a "most coverage points per timestep" basis.
comp_cdds | Pointer to compressed CDD coverage structure array to re-sort | |
comp_cdd_num | Number of elements in comp-cdds array | |
ranked_merged | Array for recalculating uniqueness of sorted elements | |
num_ranked | Number of elements in ranked_merged array |
References cp_depth, CP_TYPE_NUM, num_cps, PROFILE, PROFILE_END, UL_DIV, UL_MOD, and comp_cdd_cov_s::unique_cps.
Referenced by rank_perform().
01280 { PROFILE(RANK_PERFORM_GREEDY_SORT); 01281 01282 unsigned int i, j, k, l; 01283 unsigned int best; 01284 uint64 x; 01285 comp_cdd_cov* tmp; 01286 01287 /* First, reset the ranked_merged array */ 01288 for( x=0; x<num_ranked; x++ ) { 01289 ranked_merged[x] = 0; 01290 } 01291 01292 /* Rank based on most unique from previously ranked CDDs */ 01293 for( i=0; i<comp_cdd_num; i++ ) { 01294 best = i; 01295 for( j=i; j<comp_cdd_num; j++ ) { 01296 x = 0; 01297 comp_cdds[j]->unique_cps = 0; 01298 for( k=0; k<CP_TYPE_NUM; k++ ) { 01299 for( l=0; l<num_cps[k]; l++ ) { 01300 if( comp_cdds[j]->cps[k][UL_DIV(l)] & ((ulong)0x1 << UL_MOD(l)) ) { 01301 if( ranked_merged[x] < cp_depth ) { 01302 comp_cdds[j]->unique_cps++; 01303 } 01304 } 01305 x++; 01306 } 01307 } 01308 if( (comp_cdds[best]->unique_cps < comp_cdds[j]->unique_cps) || 01309 ((comp_cdds[best]->unique_cps == comp_cdds[j]->unique_cps) && (comp_cdds[best]->timesteps < comp_cdds[j]->timesteps)) || 01310 ((comp_cdds[best]->unique_cps == 0) && !comp_cdds[best]->required && !comp_cdds[i]->required) ) { 01311 best = j; 01312 } 01313 } 01314 tmp = comp_cdds[i]; 01315 comp_cdds[i] = comp_cdds[best]; 01316 comp_cdds[best] = tmp; 01317 x = 0; 01318 for( j=0; j<CP_TYPE_NUM; j++ ) { 01319 for( k=0; k<num_cps[j]; k++ ) { 01320 if( comp_cdds[i]->cps[j][UL_DIV(k)] & ((ulong)0x1 << UL_MOD(k)) ) { 01321 ranked_merged[x]++; 01322 } 01323 x++; 01324 } 01325 } 01326 } 01327 01328 PROFILE_END; 01329 01330 }
static void rank_perform_weighted_selection | ( | comp_cdd_cov ** | comp_cdds, | |
unsigned int | comp_cdd_num, | |||
uint16 * | ranked_merged, | |||
uint16 * | unranked_merged, | |||
unsigned int | next_cdd, | |||
unsigned int * | cdds_ranked | |||
) | [static] |
Performs ranking according to scores that are calculated from the user-specified weights and the amount of coverage points left to be hit. Ranks all compressed CDD coverage structures between next_cdd and the end of the array (comp_cdd_num - 1), inclusive.
comp_cdds | Reference to partially sorted list of compressed CDD coverage structures to sort | |
comp_cdd_num | Number of compressed CDD coverage structures in the comp_cdds array | |
ranked_merged | Array of ranked merged information from all of the compressed CDD coverage structures | |
unranked_merged | Array of unranked merged information from all of the compressed CDD coverage structures | |
next_cdd | Next index in comp_cdds array to set | |
cdds_ranked | Number of CDDs that were ranked with unique coverage in this function |
References cdd_type_weight, cp_depth, CP_TYPE_NUM, FALSE, num_cps, PROFILE, PROFILE_END, rank_selected_cdd_cov(), comp_cdd_cov_s::score, TRUE, UL_DIV, and UL_MOD.
Referenced by rank_perform().
01225 { PROFILE(RANK_PERFORM_WEIGHTED_SELECTION); 01226 01227 /* Perform this loop for each remaining coverage file */ 01228 for( ; next_cdd<comp_cdd_num; next_cdd++ ) { 01229 01230 unsigned int i, j, k; 01231 unsigned int highest_score = next_cdd; 01232 01233 /* Calculate current scores */ 01234 for( i=next_cdd; i<comp_cdd_num; i++ ) { 01235 bool unique_found = FALSE; 01236 uint64 x = 0; 01237 comp_cdds[i]->score = 0; 01238 for( j=0; j<CP_TYPE_NUM; j++ ) { 01239 unsigned int total = 0; 01240 for( k=0; k<num_cps[j]; k++ ) { 01241 if( unranked_merged[x] > 0 ) { 01242 if( comp_cdds[i]->cps[j][UL_DIV(k)] & ((ulong)0x1 << UL_MOD(k)) ) { 01243 total++; 01244 if( ranked_merged[x] < cp_depth ) { 01245 unique_found = TRUE; 01246 } 01247 } 01248 } 01249 x++; 01250 } 01251 comp_cdds[i]->score += ((total / (float)comp_cdds[i]->timesteps) * 100) * cdd_type_weight[j]; 01252 } 01253 if( (comp_cdds[i]->score > comp_cdds[highest_score]->score) && unique_found ) { 01254 highest_score = i; 01255 } 01256 } 01257 01258 /* Store the selected CDD into the next slot of the comp_cdds array */ 01259 rank_selected_cdd_cov( comp_cdds, comp_cdd_num, ranked_merged, unranked_merged, next_cdd, highest_score ); 01260 01261 /* Increment the number of unique_cps ranked */ 01262 if( comp_cdds[next_cdd]->unique_cps > 0 ) { 01263 (*cdds_ranked)++; 01264 } 01265 01266 } 01267 01268 PROFILE_END; 01269 01270 }
static void rank_read_cdd | ( | const char * | cdd_name, | |
bool | required, | |||
bool | first, | |||
comp_cdd_cov *** | comp_cdds, | |||
unsigned int * | comp_cdd_num | |||
) | [static] |
Parses the given CDD name and stores its coverage point information in a compressed format.
cdd_name | Filename of CDD file to read in | |
required | Specifies if CDD file is required to be ranked | |
first | Set to TRUE if this if the first CDD being read | |
comp_cdds | Pointer to compressed CDD array | |
comp_cdd_num | Number of compressed CDD structures in comp_cdds array |
References bind_perform(), Catch_anonymous, CP_TYPE_NUM, db_close(), db_read(), FATAL, inst_link_s::inst, db_s::inst_head, inst_link_s::next, num_cps, num_timesteps, print_output(), PROFILE, PROFILE_END, rank_calc_num_cps(), rank_create_comp_cdd_cov(), rank_dealloc_comp_cdd_cov(), rank_gather_comp_cdd_cov(), READ_MODE_REPORT_NO_MERGE, realloc_safe, report_gather_instance_stats(), Throw, TRUE, Try, user_msg, and USER_MSG_LENGTH.
Referenced by command_rank().
01073 { PROFILE(RANK_READ_CDD); 01074 01075 comp_cdd_cov* comp_cov = NULL; 01076 01077 Try { 01078 01079 inst_link* instl; 01080 uint64 tmp_nums[CP_TYPE_NUM] = {0}; 01081 01082 /* Read in database */ 01083 (void)db_read( cdd_name, READ_MODE_REPORT_NO_MERGE ); 01084 bind_perform( TRUE, 0 ); 01085 01086 /* Calculate the num_cps array if we are the first or check our coverage points to verify that they match */ 01087 instl = db_list[0]->inst_head; 01088 while( instl != NULL ) { 01089 report_gather_instance_stats( instl->inst ); 01090 if( first ) { 01091 rank_calc_num_cps( instl->inst, num_cps ); 01092 } else { 01093 rank_calc_num_cps( instl->inst, tmp_nums ); 01094 } 01095 instl = instl->next; 01096 } 01097 01098 /* If we are not the first CDD file being read in, verify that our values match */ 01099 if( !first ) { 01100 unsigned int i; 01101 for( i=0; i<CP_TYPE_NUM; i++ ) { 01102 if( num_cps[i] != tmp_nums[i] ) { 01103 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "CDD file \"%s\" does not match previously read CDD files", cdd_name ); 01104 assert( rv < USER_MSG_LENGTH ); 01105 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 01106 Throw 0; 01107 } 01108 } 01109 } 01110 01111 /* Allocate the memory needed for the compressed CDD coverage structure */ 01112 comp_cov = rank_create_comp_cdd_cov( cdd_name, required, num_timesteps ); 01113 01114 /* Finally, populate compressed CDD coverage structure with coverage information from database signals */ 01115 instl = db_list[0]->inst_head; 01116 while( instl != NULL ) { 01117 rank_gather_comp_cdd_cov( instl->inst, comp_cov ); 01118 instl = instl->next; 01119 } 01120 01121 /* Add compressed CDD coverage structure to array */ 01122 *comp_cdds = (comp_cdd_cov**)realloc_safe( *comp_cdds, (sizeof( comp_cdd_cov* ) * (*comp_cdd_num)), (sizeof( comp_cdd_cov* ) * (*comp_cdd_num + 1)) ); 01123 (*comp_cdds)[*comp_cdd_num] = comp_cov; 01124 (*comp_cdd_num)++; 01125 01126 } Catch_anonymous { 01127 db_close(); 01128 rank_dealloc_comp_cdd_cov( comp_cov ); 01129 Throw 0; 01130 } 01131 01132 /* Close the database */ 01133 db_close(); 01134 01135 PROFILE_END; 01136 01137 }
static void rank_selected_cdd_cov | ( | comp_cdd_cov ** | comp_cdds, | |
unsigned int | comp_cdd_num, | |||
uint16 * | ranked_merged, | |||
uint16 * | unranked_merged, | |||
unsigned int | next_cdd, | |||
unsigned int | selected_cdd | |||
) | [static] |
Sorts the selected CDD coverage structure into the comp_cdds list and performs post-placement calculations.
comp_cdds | Pointer to array of compressed CDD coverage structures being sorted | |
comp_cdd_num | Total number of elements in comp_cdds array | |
ranked_merged | Array of merged information for ranked CDDs | |
unranked_merged | Array of merged information for unranked CDDs | |
next_cdd | Index into comp_cdds array that the selected CDD should be stored at | |
selected_cdd | Index into comp_cdds array of the selected CDD for ranking |
References cp_depth, CP_TYPE_NUM, debug_mode, num_cps, PROFILE, PROFILE_END, quiet_mode, rank_verbose, terse_mode, UL_DIV, UL_MOD, and comp_cdd_cov_s::unique_cps.
Referenced by rank_perform(), and rank_perform_weighted_selection().
01151 { PROFILE(RANK_SELECTED_CDD_COV); 01152 01153 unsigned int i, j; 01154 uint64 merged_index = 0; 01155 static unsigned int dots_output = 0; 01156 comp_cdd_cov* tmp; 01157 01158 /* Output status indicator, if necessary */ 01159 if( ((!quiet_mode && !terse_mode) || debug_mode) && !rank_verbose ) { 01160 while( ((unsigned int)(((next_cdd + 1) / (float)comp_cdd_num) * 100) - (dots_output * 10)) >= 10 ) { 01161 unsigned int rv; 01162 printf( "." ); 01163 rv = fflush( stdout ); 01164 assert( rv == 0 ); 01165 dots_output++; 01166 } 01167 } 01168 01169 /* Move the most unique CDD to the next position */ 01170 tmp = comp_cdds[next_cdd]; 01171 comp_cdds[next_cdd] = comp_cdds[selected_cdd]; 01172 comp_cdds[selected_cdd] = tmp; 01173 01174 /* Zero out uniqueness value */ 01175 comp_cdds[next_cdd]->unique_cps = 0; 01176 01177 /* Subtract all of the set coverage points from the merged value */ 01178 for( i=0; i<CP_TYPE_NUM; i++ ) { 01179 for( j=0; j<num_cps[i]; j++ ) { 01180 if( unranked_merged[merged_index] > 0 ) { 01181 if( comp_cdds[next_cdd]->cps[i][UL_DIV(j)] & ((ulong)0x1 << UL_MOD(j)) ) { 01182 /* 01183 If we have not seen this coverage point get hit the needed "depth" amount in the ranked 01184 list, increment the unique_cps value for the selected compressed CDD coverage structure. 01185 */ 01186 if( ranked_merged[merged_index] < cp_depth ) { 01187 comp_cdds[next_cdd]->unique_cps++; 01188 } 01189 unranked_merged[merged_index]--; 01190 ranked_merged[merged_index]++; 01191 } 01192 } 01193 merged_index++; 01194 } 01195 } 01196 01197 if( ((!quiet_mode && !terse_mode) || debug_mode) && !rank_verbose ) { 01198 if( (next_cdd + 1) == comp_cdd_num ) { 01199 unsigned int rv; 01200 if( dots_output < 10 ) { 01201 printf( "." ); 01202 } 01203 printf( "\n" ); 01204 rv = fflush( stdout ); 01205 assert( rv == 0 ); 01206 } 01207 } 01208 01209 PROFILE_END; 01210 01211 }
static void rank_usage | ( | ) | [static] |
Outputs usage information to standard output for rank command.
Referenced by rank_parse_args().
00237 { 00238 00239 printf( "\n" ); 00240 printf( "Usage: covered rank (-h | ([<options>] <database_to_rank> <database_to_rank>+)\n" ); 00241 printf( "\n" ); 00242 printf( " -h Displays this help information.\n" ); 00243 printf( "\n" ); 00244 printf( " Options:\n" ); 00245 printf( " -depth <number> Specifies the minimum number of CDD files to hit each coverage point.\n" ); 00246 printf( " The value of <number> should be a value of 1 or more. Default is 1.\n" ); 00247 printf( " -names-only If specified, outputs only the needed CDD filenames that need to be\n" ); 00248 printf( " run in the order they need to be run. If this option is not set, a\n" ); 00249 printf( " report-style output is provided with additional information.\n" ); 00250 printf( " -f <filename> Name of file containing additional arguments to parse.\n" ); 00251 printf( " -required-list <filename> Name of file containing list of CDD files which are required to be in the\n" ); 00252 printf( " list of ranked CDDs to be run.\n" ); 00253 printf( " -required-cdd <filename> Name of CDD file that is required to be in the list of ranked CDDs to be run.\n" ); 00254 printf( " -d <directory> Directory to search for CDD files to include. This option is used in\n" ); 00255 printf( " conjunction with the -ext option which specifies the file extension\n" ); 00256 printf( " to use for determining which files in the directory are CDD files.\n" ); 00257 printf( " -ext <extension> Used in conjunction with the -d option. If no -ext options are specified\n" ); 00258 printf( " on the command-line, the default value of '.cdd' is used. Note that\n" ); 00259 printf( " a period (.) should be specified.\n" ); 00260 printf( " -o <filename> Name of file to output ranking information to. Default is stdout.\n" ); 00261 printf( " -weight-line <number> Specifies a relative weighting for line coverage used to rank\n" ); 00262 printf( " non-unique coverage points. A value of 0 removes line coverage\n" ); 00263 printf( " from ranking consideration. Default value is 1.\n" ); 00264 printf( " -weight-toggle <number> Specifies a relative weighting for toggle coverage used to rank\n" ); 00265 printf( " non-unique coverage points. A value of 0 removes toggle coverage\n" ); 00266 printf( " from ranking consideration. Default value is 1.\n" ); 00267 printf( " -weight-memory <number> Specifies a relative weighting for memory coverage used to rank\n" ); 00268 printf( " non-unique coverage points. A value of 0 removes memory coverage\n" ); 00269 printf( " from ranking consideration. Default value is 1.\n" ); 00270 printf( " -weight-comb <number> Specifies a relative weighting for combinational logic coverage used\n" ); 00271 printf( " to rank non-unique coverage points. A value of 0 removes combinational\n" ); 00272 printf( " logic coverage from ranking consideration. Default value is 1.\n" ); 00273 printf( " -weight-fsm <number> Specifies a relative weighting for FSM state/state transition coverage\n" ); 00274 printf( " used to rank non-unique coverage points. A value of 0 removes FSM\n" ); 00275 printf( " coverage from ranking consideration. Default value is 1.\n" ); 00276 printf( " -weight-assert <number> Specifies a relative weighting for assertion coverage used to rank\n" ); 00277 printf( " non-unique coverage points. A value of 0 removes assertion coverage\n" ); 00278 printf( " from ranking consideration. Default value is 0.\n" ); 00279 printf( " -v Outputs verbose information during the rank selection process. This output\n" ); 00280 printf( " is not for debugging purposes, but rather gives the user insight into\n" ); 00281 printf( " what's going on \"behind the scenes\" during the ranking process.\n" ); 00282 printf( "\n" ); 00283 00284 }
Controls whether multi-expressions are used or not.
Referenced by combination_get_tree_stats(), and command_rank().
bool cdd_type_set[CP_TYPE_NUM] = {0} [static] |
Set to TRUE when the user has specified the corresponding weight value on the command-line. Allows us to display a warning message to the user when multiple values are specified.
Referenced by rank_parse_args().
unsigned int cdd_type_weight[CP_TYPE_NUM] = {1,1,1,1,1,0} [static] |
Array containing the weights to be used for each of the CDD metric types.
Referenced by rank_parse_args(), and rank_perform_weighted_selection().
unsigned int cp_depth = 0 [static] |
Specifies the number of CDDs that must hit each coverage point before a CDD will be considered unneeded.
Referenced by rank_parse_args(), rank_perform_greedy_sort(), rank_perform_weighted_selection(), and rank_selected_cdd_cov().
If set to TRUE, causes debug information to be spewed to screen.
const exp_info exp_op_info[EXP_OP_NUM] |
Array containing static information about expression operation types. NOTE: This structure MUST be updated if a new expression is added! The third argument is an initialization to the exp_info_s structure.
bool flag_names_only = FALSE [static] |
If set to TRUE, outputs only the names of the CDD files in the order that they should be run. This value is set to TRUE when the -names_only option is specified.
Referenced by rank_output(), and rank_parse_args().
int64 largest_malloc_size |
Holds the largest number of bytes in allocation at one period of time.
Referenced by calloc_safe1(), command_rank(), command_score(), malloc_safe1(), malloc_safe_nolimit1(), realloc_safe1(), and strdup_safe1().
unsigned int longest_name_len = 0 [static] |
Specifies the string length of the longest CDD name
Referenced by rank_create_comp_cdd_cov(), and rank_output().
uint64 num_cps[CP_TYPE_NUM] = {0} [static] |
Array containing the number of coverage points for each metric for all compressed CDD coverage structures.
Referenced by rank_check_index(), rank_create_comp_cdd_cov(), rank_dealloc_comp_cdd_cov(), rank_output(), rank_perform(), rank_perform_greedy_sort(), rank_perform_weighted_selection(), rank_read_cdd(), and rank_selected_cdd_cov().
uint64 num_timesteps |
Specifies the number of timesteps that have transpired during this simulation.
Referenced by db_do_timestep(), info_db_read(), info_db_write(), and rank_read_cdd().
If set to TRUE, suppresses all non-warning/fatal error messages from being displayed.
Referenced by print_output(), rank_perform(), rank_selected_cdd_cov(), and set_quiet().
char* rank_file = NULL [static] |
File to be used for outputting rank information.
Referenced by command_rank(), rank_output(), and rank_parse_args().
str_link* rank_in_head = NULL [static] |
Pointer to head of list of CDD filenames that need to be read in.
str_link* rank_in_tail = NULL [static] |
Pointer to tail of list of CDD filenames that need to be read in.
bool rank_verbose = FALSE [static] |
If set to TRUE, outputs behind the scenes output during the rank selection process.
Referenced by command_rank(), rank_parse_args(), rank_perform(), and rank_selected_cdd_cov().
If set to a boolean value of TRUE, reports the assertion coverage for the specified database file; otherwise, omits assertion coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), report_parse_args(), and report_parse_metrics().
If set to a boolean value of TRUE, reports the combinational logic coverage for the specified database file; otherwise, omits combinational logic coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), and report_parse_metrics().
If set to a boolean value of TRUE, reports the finite state machine coverage for the specified database file; otherwise, omits finite state machine coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), and report_parse_metrics().
If set to a boolean value of TRUE, reports the line coverage for the specified database file; otherwise, omits line coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), and report_parse_metrics().
If set to a boolean value of TRUE, reports the memory coverage for the specified database file; otherwise, omits memory coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), report_parse_args(), and report_parse_metrics().
If set to a boolean value of TRUE, reports the toggle coverage for the specified database file; otherwise, omits toggle coverage from the report output.
Referenced by command_rank(), report_gather_funit_stats(), report_gather_instance_stats(), report_generate(), and report_parse_metrics().
If set to TRUE, suppresses all normal messages from being displayed.
Referenced by print_output(), rank_perform(), rank_selected_cdd_cov(), and set_terse().
char user_msg[USER_MSG_LENGTH] |
Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.