fsm.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "arc.h"
#include "binding.h"
#include "codegen.h"
#include "db.h"
#include "defines.h"
#include "exclude.h"
#include "expr.h"
#include "func_unit.h"
#include "fsm.h"
#include "link.h"
#include "obfuscate.h"
#include "ovl.h"
#include "report.h"
#include "sim.h"
#include "util.h"
#include "vector.h"

Functions

fsmfsm_create (expression *from_state, expression *to_state, int line, bool exclude)
 Creates and initializes new FSM structure.
void fsm_add_arc (fsm *table, expression *from_state, expression *to_state)
void fsm_create_tables (fsm *table)
 Sets sizes of tables in specified FSM structure.
void fsm_db_write (fsm *table, FILE *file, bool ids_issued)
 Outputs contents of specified FSM to CDD file.
void fsm_db_read (char **line, func_unit *funit)
 Reads in contents of specified FSM.
void fsm_db_merge (fsm *base, char **line)
 Reads and merges two FSMs, placing result into base FSM.
void fsm_merge (fsm *base, fsm *other)
 Merges two FSMs, placing the result into the base FSM.
void fsm_table_set (expression *expr, const sim_time *time)
 Sets the bit in set table based on the values of last and curr.
void fsm_get_stats (fsm_link *table, int *state_hit, int *state_total, int *arc_hit, int *arc_total, int *arc_excluded)
 Gathers statistics about the current FSM.
void fsm_get_funit_summary (func_unit *funit, int *hit, int *excluded, int *total)
void fsm_get_inst_summary (funit_inst *inst, int *hit, int *excluded, int *total)
 Retrieves the FSM summary information for the specified functional unit.
static void fsm_gather_signals (expression *expr, sig_link **head, sig_link **tail, int expr_id, int **expr_ids, int *expr_id_size)
void fsm_collect (func_unit *funit, int cov, sig_link **sig_head, sig_link **sig_tail, int **expr_ids, int **excludes)
 Retrieves covered or uncovered FSMs from the specified functional unit.
void fsm_get_coverage (func_unit *funit, int expr_id, char ***total_fr_states, unsigned int *total_fr_state_num, char ***total_to_states, unsigned int *total_to_state_num, char ***hit_fr_states, unsigned int *hit_fr_state_num, char ***hit_to_states, unsigned int *hit_to_state_num, char ***total_from_arcs, char ***total_to_arcs, int **total_ids, int **excludes, char ***reasons, int *total_arc_num, char ***hit_from_arcs, char ***hit_to_arcs, int *hit_arc_num, char ***input_state, unsigned int *input_size, char ***output_state, unsigned int *output_size)
 Collects all coverage information for the specified FSM.
static bool fsm_display_instance_summary (FILE *ofile, const char *name, int state_hit, int state_total, int arc_hit, int arc_total)
static bool fsm_instance_summary (FILE *ofile, funit_inst *root, char *parent_inst, int *state_hits, int *state_total, int *arc_hits, int *arc_total)
static bool fsm_display_funit_summary (FILE *ofile, const char *name, const char *fname, int state_hits, int state_total, int arc_hits, int arc_total)
static bool fsm_funit_summary (FILE *ofile, funit_link *head, int *state_hits, int *state_total, int *arc_hits, int *arc_total)
static void fsm_display_state_verbose (FILE *ofile, fsm *table)
static bool fsm_display_arc_verbose (FILE *ofile, fsm *table, func_unit *funit, rpt_type rtype)
static void fsm_display_verbose (FILE *ofile, func_unit *funit)
static void fsm_instance_verbose (FILE *ofile, funit_inst *root, char *parent_inst)
static void fsm_funit_verbose (FILE *ofile, funit_link *head)
void fsm_report (FILE *ofile, bool verbose)
 Generates report output for FSM coverage.
void fsm_dealloc (fsm *table)
 Deallocates specified FSM structure.

Variables

db ** db_list
unsigned int curr_db
bool report_covered
unsigned int report_comb_depth
bool report_instance
char user_msg [USER_MSG_LENGTH]
isuppl info_suppl
bool report_exclusions
bool flag_output_exclusion_ids

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
3/31/2002
What is an FSM?
An Finite State Machine (FSM) consists of basically three elements:
  1. Pointer to an input state expression
  2. Pointer to an output state expression
  3. Pointer to an FSM arc (please see arc.c for more information)

Function Documentation

void fsm_add_arc ( fsm table,
expression from_state,
expression to_state 
)

Adds new FSM arc structure to specified FSMs arc list.

Parameters:
table Pointer to FSM structure to add new arc to
from_state Pointer to from_state expression to add
to_state Pointer to to_state expression to add

References fsm_s::arc_head, fsm_s::arc_tail, fsm_arc_s::from_state, malloc_safe, fsm_arc_s::next, PROFILE, PROFILE_END, and fsm_arc_s::to_state.

Referenced by fsm_arg_parse_trans().

00103   { PROFILE(FSM_ADD_ARC);
00104 
00105   fsm_arc* arc;  /* Pointer to newly created FSM arc structure */
00106 
00107   /* Create an initialize specified arc */
00108   arc             = (fsm_arc*)malloc_safe( sizeof( fsm_arc ) );
00109   arc->from_state = from_state;
00110   arc->to_state   = to_state;
00111   arc->next       = NULL;
00112 
00113   /* Add new arc to specified FSM structure */
00114   if( table->arc_head == NULL ) {
00115     table->arc_head = table->arc_tail = arc;
00116   } else {
00117     table->arc_tail->next = arc;
00118     table->arc_tail       = arc;
00119   }
00120 
00121   PROFILE_END;
00122 
00123 }

void fsm_collect ( func_unit funit,
int  cov,
sig_link **  sig_head,
sig_link **  sig_tail,
int **  expr_ids,
int **  excludes 
)

Retrieves covered or uncovered FSMs from the specified functional unit.

Gathers the covered or uncovered FSM information, storing their expressions in the sig_head/sig_tail signal list. Used by the GUI for verbose FSM output.

Parameters:
funit Pointer to functional unit
cov Specifies if we are attempting to get uncovered (0) or covered (1) FSMs
sig_head Pointer to the head of the signal list of covered FSM output states
sig_tail Pointer to the tail of the signal list of covered FSM output states
expr_ids Pointer to array of expression IDs for each uncovered signal
excludes Pointer to array of exclude values for each uncovered signal

References arc_are_any_excluded(), arc_get_stats(), fsm_gather_signals(), func_unit_s::fsm_head, expression_s::id, fsm_link_s::next, PROFILE, PROFILE_END, realloc_safe, fsm_s::table, fsm_link_s::table, and fsm_s::to_state.

00522   { PROFILE(FSM_COLLECT);
00523 
00524   fsm_link* curr_fsm;  /* Pointer to current FSM link being evaluated */
00525   int       size = 0;  /* Number of expressions IDs stored in expr_ids array */
00526 
00527   /* Initialize list pointers */
00528   *sig_tail = *sig_head = NULL;
00529   *expr_ids = *excludes = NULL;
00530 
00531   curr_fsm = funit->fsm_head;
00532   while( curr_fsm != NULL ) {
00533 
00534     /* Get the state and arc statistics */
00535     int state_hit    = 0;
00536     int state_total  = 0;
00537     int arc_hit      = 0;
00538     int arc_total    = 0;
00539     int arc_excluded = 0;
00540     arc_get_stats( curr_fsm->table->table, &state_hit, &state_total, &arc_hit, &arc_total, &arc_excluded );
00541 
00542     /* Allocate some more memory for the excluded array */
00543     *excludes = (int*)realloc_safe( *excludes, (sizeof( int ) * size), (sizeof( int ) * (size + 1)) );
00544 
00545     /* If the total number of arcs is not known, consider this FSM as uncovered */
00546     if( (cov == 0) && ((arc_total == -1) || (arc_total != arc_hit)) ) {
00547       (*excludes)[size] = 0;
00548       fsm_gather_signals( curr_fsm->table->to_state, sig_head, sig_tail, curr_fsm->table->to_state->id, expr_ids, &size );
00549     } else {
00550       if( (cov == 0) && arc_are_any_excluded( curr_fsm->table->table ) ) {
00551         fsm_gather_signals( curr_fsm->table->to_state, sig_head, sig_tail, curr_fsm->table->to_state->id, expr_ids, &size );
00552         (*excludes)[size] = 1;
00553       } else if( cov == 1 ) {
00554         fsm_gather_signals( curr_fsm->table->to_state, sig_head, sig_tail, -1, expr_ids, &size );
00555       }
00556     }
00557 
00558     curr_fsm = curr_fsm->next;
00559 
00560   }
00561 
00562   PROFILE_END;
00563 
00564 }

fsm* fsm_create ( expression from_state,
expression to_state,
int  line,
bool  exclude 
)

Creates and initializes new FSM structure.

Returns:
Returns a pointer to the newly allocated FSM structure.

Allocates and initializes an FSM structure.

Parameters:
from_state Pointer to expression that is input state variable for this FSM
to_state Pointer to expression that is output state variable for this FSM
line First line of FSM attribute
exclude Value to set the exclude bit to

References fsm_s::arc_head, fsm_s::arc_tail, fsm_s::exclude, fsm_s::from_state, fsm_s::line, malloc_safe, fsm_s::name, PROFILE, fsm_s::table, and fsm_s::to_state.

Referenced by fsm_db_read(), fsm_var_add(), and fsm_var_bind_stmt().

00078   { PROFILE(FSM_CREATE);
00079 
00080   fsm* table;  /* Pointer to newly created FSM */
00081 
00082   table             = (fsm*)malloc_safe( sizeof( fsm ) );
00083   table->name       = NULL;
00084   table->line       = line;
00085   table->from_state = from_state;
00086   table->to_state   = to_state;
00087   table->arc_head   = NULL;
00088   table->arc_tail   = NULL;
00089   table->table      = NULL;
00090   table->exclude    = exclude;
00091 
00092   return( table );
00093 
00094 }

void fsm_create_tables ( fsm table  ) 

Sets sizes of tables in specified FSM structure.

After the FSM signals are sized, this function is called to size an FSM structure (allocate memory for its tables) and the associated FSM arc list is parsed, setting the appropriate bit in the valid table.

Parameters:
table Pointer to FSM structure to set table sizes to

References arc_add(), arc_create(), fsm_s::arc_head, fsm_s::exclude, expression_operate(), FALSE, sim_time_s::final, fsm_arc_s::from_state, sim_time_s::full, sim_time_s::hi, sim_time_s::lo, fsm_arc_s::next, PROFILE, PROFILE_END, fsm_s::table, fsm_arc_s::to_state, fsm_s::to_state, TRUE, expression_s::value, and vector_s::width.

Referenced by funit_size_elements().

00132   { PROFILE(FSM_CREATE_TABLES);
00133 
00134   fsm_arc* curr_arc;    /* Pointer to current FSM arc structure */
00135   bool     set = TRUE;  /* Specifies if specified bit was set */
00136   sim_time time;        /* Current simulation time */
00137 
00138   /* Create the FSM arc transition table */
00139   assert( table != NULL );
00140   assert( table->to_state != NULL );
00141   assert( table->to_state->value != NULL );
00142   assert( table->table == NULL );
00143   table->table = arc_create( table->to_state->value->width );
00144 
00145   /* Initialize the current time */
00146   time.lo    = 0;
00147   time.hi    = 0;
00148   time.full  = 0;
00149   time.final = FALSE;
00150 
00151   /* Set valid table */
00152   curr_arc = table->arc_head;
00153   while( (curr_arc != NULL) && set ) {
00154 
00155     /* Evaluate from and to state expressions */
00156     (void)expression_operate( curr_arc->from_state, NULL, &time );
00157     (void)expression_operate( curr_arc->to_state, NULL, &time );
00158 
00159     /* Set table entry in table, if possible */
00160     arc_add( table->table, curr_arc->from_state->value, curr_arc->to_state->value, 0, table->exclude );
00161 
00162     curr_arc = curr_arc->next;
00163 
00164   } 
00165 
00166   PROFILE_END;
00167 
00168 }

void fsm_db_merge ( fsm base,
char **  line 
)

Reads and merges two FSMs, placing result into base FSM.

Parameters:
base Pointer to FSM structure to merge data into.
line Pointer to read in line from CDD file to merge.
Exceptions:
anonymous arc_db_merge Throw

Parses specified line for FSM information and performs merge of the base and in FSMs, placing the resulting merged FSM into the base signal. If the FSMs are found to be unalike (names are different), an error message is displayed to the user. If both FSMs are the same, perform the merge on the FSM's tables.

References arc_db_merge(), FATAL, fsm_s::from_state, print_output(), PROFILE, PROFILE_END, fsm_s::table, Throw, and fsm_s::to_state.

Referenced by funit_db_inst_merge(), and funit_db_mod_merge().

00319   { PROFILE(FSM_DB_MERGE);
00320 
00321   int fline;       /* First line number of FSM */
00322   int iid;         /* Input state variable expression ID */
00323   int oid;         /* Output state variable expression ID */
00324   int chars_read;  /* Number of characters read from line */
00325   int is_table;    /* Holds value of is_table signifier */
00326 
00327   assert( base != NULL );
00328   assert( base->from_state != NULL );
00329   assert( base->to_state != NULL );
00330 
00331   if( sscanf( *line, "%d %d %d %d%n", &fline, &iid, &oid, &is_table, &chars_read ) == 4 ) {
00332 
00333     *line = *line + chars_read + 1;
00334 
00335     if( is_table == 1 ) {
00336 
00337       arc_db_merge( base->table, line );
00338           
00339     }
00340 
00341   } else {
00342 
00343     print_output( "Database being merged is not compatible with the original database.", FATAL, __FILE__, __LINE__ );
00344     Throw 0;
00345 
00346   }
00347 
00348   PROFILE_END;
00349 
00350 }

void fsm_db_read ( char **  line,
func_unit funit 
)

Reads in contents of specified FSM.

Parameters:
line Pointer to current line being read from the CDD file.
funit Pointer to current functional unit.
Exceptions:
anonymous expression_create Throw Throw Throw Throw arc_db_read

Reads in contents of FSM line from CDD file and stores newly created FSM into the specified functional unit.

References arc_db_read(), bind_append_fsm_expr(), Catch_anonymous, exp_link_s::exp, func_unit_s::exp_head, exp_link_find(), EXP_OP_STATIC, expression_create(), FALSE, FATAL, fsm_s::from_state, fsm_create(), fsm_dealloc(), func_unit_s::fsm_head, fsm_link_add(), func_unit_s::fsm_tail, print_output(), PROFILE, PROFILE_END, fsm_s::table, expression_s::table, Throw, fsm_s::to_state, Try, user_msg, USER_MSG_LENGTH, expression_s::value, and vector_dealloc().

Referenced by db_read(), and funit_db_mod_merge().

00218   { PROFILE(FSM_DB_READ);
00219 
00220   int        fline;       /* First line of FSM attribute */
00221   int        iexp_id;     /* Input expression ID */
00222   int        oexp_id;     /* Output expression ID */
00223   exp_link*  iexpl;       /* Pointer to found state variable */
00224   exp_link*  oexpl;       /* Pointer to found state variable */
00225   int        chars_read;  /* Number of characters read from sscanf */
00226   fsm*       table;       /* Pointer to newly created FSM structure from CDD */
00227   int        is_table;    /* Holds value of is_table entry of FSM output */
00228  
00229   if( sscanf( *line, "%d %d %d %d%n", &fline, &iexp_id, &oexp_id, &is_table, &chars_read ) == 4 ) {
00230 
00231     *line = *line + chars_read + 1;
00232 
00233     if( funit == NULL ) {
00234 
00235       print_output( "Internal error:  FSM in database written before its functional unit", FATAL, __FILE__, __LINE__ );
00236       Throw 0;
00237 
00238     } else {
00239 
00240       /* Find specified signal */
00241       if( ((iexpl = exp_link_find( iexp_id, funit->exp_head )) != NULL) &&
00242           ((oexpl = exp_link_find( oexp_id, funit->exp_head )) != NULL) ) {
00243 
00244         /* Create new FSM */
00245         table = fsm_create( iexpl->exp, oexpl->exp, fline, FALSE );
00246 
00247         /*
00248          If the input state variable is the same as the output state variable, create the new expression now.
00249         */
00250         if( iexp_id == oexp_id ) {
00251           Try {
00252             table->from_state = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, iexp_id, 0, 0, 0, FALSE );
00253           } Catch_anonymous {
00254             fsm_dealloc( table );
00255             Throw 0;
00256           }
00257           vector_dealloc( table->from_state->value );
00258           bind_append_fsm_expr( table->from_state, iexpl->exp, funit );
00259         } else {
00260           table->from_state = iexpl->exp;
00261         }
00262 
00263         /* Set input/output expression tables to point to this FSM */
00264         table->from_state->table = table;
00265         table->to_state->table   = table;
00266   
00267         /* Now read in set table */
00268         if( is_table == 1 ) {
00269 
00270           Try {
00271             arc_db_read( &(table->table), line );
00272           } Catch_anonymous {
00273             fsm_dealloc( table );
00274             Throw 0;
00275           }
00276 
00277         }
00278 
00279         /* Add fsm to current functional unit */
00280         fsm_link_add( table, &(funit->fsm_head), &(funit->fsm_tail) );
00281  
00282       } else {
00283 
00284         unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Unable to find state variable expressions (%d, %d) for current FSM", iexp_id, oexp_id );
00285         assert( rv < USER_MSG_LENGTH );
00286         print_output( user_msg, FATAL, __FILE__, __LINE__ );
00287         Throw 0;
00288 
00289       }
00290 
00291     }
00292 
00293   } else {
00294 
00295     print_output( "Unable to parse FSM line in database file.  Unable to read.", FATAL, __FILE__, __LINE__ );
00296     Throw 0;
00297 
00298   }
00299 
00300   PROFILE_END;
00301 
00302 }

void fsm_db_write ( fsm table,
FILE *  file,
bool  ids_issued 
)

Outputs contents of specified FSM to CDD file.

Outputs the contents of the specified FSM to the specified CDD file.

Parameters:
table Pointer to FSM structure to output
file Pointer to file output stream to write to
ids_issued Set to TRUE if expression IDs were just issued

References arc_db_write(), arc_dealloc(), DB_TYPE_FSM, expression_get_id(), fsm_s::from_state, fsm_s::line, PROFILE, PROFILE_END, fsm_s::table, and fsm_s::to_state.

Referenced by funit_db_write().

00177   { PROFILE(FSM_DB_WRITE);
00178 
00179   fprintf( file, "%d %d %d %d ",
00180     DB_TYPE_FSM,
00181     table->line,
00182     expression_get_id( table->from_state, ids_issued ),
00183     expression_get_id( table->to_state, ids_issued )
00184   );
00185 
00186   /* Print set table */
00187   if( table->table != NULL ) {
00188     fprintf( file, "1 " );
00189     arc_db_write( table->table, file );
00190 
00191     /* Deallocate the given table after writing it */
00192     if( table->table != NULL ) {
00193       arc_dealloc( table->table );
00194       table->table = NULL;
00195     }
00196   } else {
00197     fprintf( file, "0" );
00198   }
00199 
00200   fprintf( file, "\n" );
00201 
00202   PROFILE_END;
00203 
00204 } 

void fsm_dealloc ( fsm table  ) 

Deallocates specified FSM structure.

Deallocates all allocated memory for the specified FSM structure.

Parameters:
table Pointer to FSM structure to deallocate

References arc_dealloc(), fsm_s::arc_head, expression_dealloc(), FALSE, free_safe, fsm_s::from_state, fsm_arc_s::from_state, expression_s::id, fsm_s::name, fsm_arc_s::next, PROFILE, PROFILE_END, fsm_s::table, fsm_s::to_state, and fsm_arc_s::to_state.

Referenced by fsm_db_read(), and fsm_link_delete_list().

01284   { PROFILE(FSM_DEALLOC);
01285 
01286   fsm_arc* tmp;  /* Temporary pointer to current FSM arc structure to deallocate */
01287 
01288   if( table != NULL ) {
01289 
01290     /* Free name if one was specified */
01291     if( table->name != NULL ) {
01292       free_safe( table->name, (strlen( table->name ) + 1) );
01293     }
01294 
01295     /* Deallocate tables */
01296     arc_dealloc( table->table );
01297 
01298     /* Deallocate FSM arc structure */
01299     while( table->arc_head != NULL ) {
01300       tmp = table->arc_head;
01301       table->arc_head = table->arc_head->next;
01302       expression_dealloc( tmp->to_state, FALSE );
01303       expression_dealloc( tmp->from_state, FALSE );
01304       free_safe( tmp, sizeof( fsm_arc ) );
01305     }
01306 
01307     /*
01308      Deallocate from_state if it is the same expression ID as the to_state expression and is
01309      not the same expression structure
01310     */
01311     if( (table->from_state != NULL)             &&
01312         (table->to_state != NULL)               &&
01313         (table->from_state != table->to_state ) &&
01314         (table->from_state->id == table->to_state->id) ) {
01315       expression_dealloc( table->from_state, FALSE );
01316     }
01317 
01318     /* Deallocate this structure */
01319     free_safe( table, sizeof( fsm ) );
01320       
01321   }
01322 
01323   PROFILE_END;
01324 
01325 }

static bool fsm_display_arc_verbose ( FILE *  ofile,
fsm table,
func_unit funit,
rpt_type  rtype 
) [static]
Returns:
Returns TRUE if at least one arc transition was excluded.

Displays verbose information for hit/missed state transitions to the specified output file.

Parameters:
ofile File handle of output file to send report output to
table Pointer to FSM structure to output
funit Pointer to functional unit containing this FSM
rtype Specifies the type of report to generate

References arc_get_transitions(), db_gen_exclusion_id(), db_get_exclusion_id_size(), FALSE, flag_output_exclusion_ids, free_safe, fsm_s::from_state, gen_char_string(), fsuppl_u::known, malloc_safe, fsuppl_u::part, PROFILE, PROFILE_END, report_output_exclusion_reason(), RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, fsm_table_s::suppl, fsm_s::table, fsm_s::to_state, TRUE, expression_s::value, and vector_s::width.

Referenced by fsm_display_verbose().

00916   { PROFILE(FSM_DISPLAY_ARC_VERBOSE);
00917 
00918   bool         retval = FALSE;  /* Return value for this function */
00919   bool         trans_unknown;   /* Set to TRUE if the number of state transitions is known */
00920   char         fstr[100];       /* Format string */
00921   char         tmp[20];         /* Temporary string */
00922   int          width;           /* Width (in characters) of the entire output value */
00923   int          val_width;       /* Number of bits in output state expression */
00924   int          len_width;       /* Number of characters needed to store the width of the output state expression */
00925   char**       from_states;     /* String array containing from_state information */
00926   char**       to_states;       /* String array containing to_state information */
00927   int*         ids;             /* List of exclusion IDs per from/to state transition */
00928   int*         excludes;        /* List of excluded arcs */
00929   char**       reasons;         /* Exclusion reasons */
00930   int          arc_size;        /* Number of elements in the from_states and to_states arrays */
00931   int          i;               /* Loop iterator */
00932   char         tmpfst[4096];    /* Temporary string holder for from_state value */
00933   char         tmptst[4096];    /* Temporary string holder for to_state value */
00934   unsigned int rv;              /* Return value from snprintf calls */
00935   char         spaces[30];      /* Placeholder for spaces */
00936   unsigned int eid_size;
00937   char*        eid;
00938 
00939   /* Figure out if transactions were known */
00940   trans_unknown = (table->table->suppl.part.known == 0);
00941 
00942   spaces[0] = '\0';
00943 
00944   if( (rtype == RPT_TYPE_HIT) || trans_unknown ) {
00945     fprintf( ofile, "        Hit State Transitions\n\n" );
00946   } else if( rtype == RPT_TYPE_MISS ) {
00947     fprintf( ofile, "        Missed State Transitions\n\n" );
00948   } else if( rtype == RPT_TYPE_EXCL ) {
00949     fprintf( ofile, "        Excluded State Transitions\n\n" );
00950   }
00951 
00952   val_width = table->to_state->value->width;
00953 
00954   /* Calculate width of length string */
00955   rv = snprintf( tmp, 20, "%d", val_width );
00956   assert( rv < 20 );
00957   len_width = strlen( tmp );
00958 
00959   /* Create format string to hold largest output value */
00960   width = ((val_width % 4) == 0) ? (val_width / 4) : ((val_width / 4) + 1);
00961   width = width + len_width + 2;
00962   width = (width > 10) ? width : 10;
00963 
00964   /* Generate format string */
00965   rv = snprintf( fstr, 100, "          %%s%%-%d.%ds %%s %%-%d.%ds\n", width, width, width, width );
00966   assert( rv < 100 );
00967 
00968   if( flag_output_exclusion_ids && (rtype != RPT_TYPE_HIT) && !trans_unknown ) {
00969     gen_char_string( spaces, ' ', ((db_get_exclusion_id_size() - 1) + 4) );
00970     eid_size = db_get_exclusion_id_size() + 4;
00971     eid      = (char*)malloc_safe( eid_size );
00972   } else {
00973     eid_size = 1;
00974     eid      = (char*)malloc_safe( eid_size );
00975     eid[0]   = '\0';
00976   }
00977 
00978   fprintf( ofile, fstr, spaces, "From State", "  ", "To State" );
00979   fprintf( ofile, fstr, spaces, "==========", "  ", "==========" );
00980 
00981   /* Get the state transition information */
00982   arc_get_transitions( &from_states, &to_states, &ids, &excludes, &reasons, &arc_size, table->table, funit, ((rtype == RPT_TYPE_HIT) || trans_unknown), FALSE,
00983                        table->from_state->value->width, table->to_state->value->width );
00984 
00985   /* Output the information to the specified output stream */
00986   for( i=0; i<arc_size; i++ ) {
00987     exclude_reason* er;
00988     retval |= excludes[i];
00989     if( ((rtype != RPT_TYPE_EXCL) && (excludes[i] == 0)) ||
00990         ((rtype == RPT_TYPE_EXCL) && (excludes[i] == 1)) ) {
00991       rv = snprintf( tmpfst, 4096, "%s", from_states[i] );
00992       assert( rv < 4096 );
00993       rv = snprintf( tmptst, 4096, "%s", to_states[i] );
00994       assert( rv < 4096 );
00995       if( flag_output_exclusion_ids && (rtype != RPT_TYPE_HIT) && !trans_unknown ) {
00996         rv = snprintf( eid, eid_size, "(%s)  ", db_gen_exclusion_id( 'F', ids[i] ) );
00997         assert( rv < eid_size );
00998       }
00999       fprintf( ofile, fstr, eid, tmpfst, "->", tmptst );
01000     }
01001     if( (rtype == RPT_TYPE_EXCL) && (reasons[i] != NULL) ) {
01002       if( flag_output_exclusion_ids ) {
01003         report_output_exclusion_reason( ofile, (16 + (db_get_exclusion_id_size() - 1)), reasons[i], TRUE );
01004       } else {
01005         report_output_exclusion_reason( ofile, 12, reasons[i], TRUE );
01006       }
01007     }
01008     free_safe( from_states[i], (strlen( from_states[i] ) + 1) );
01009     free_safe( to_states[i], (strlen( to_states[i] ) + 1) );
01010     free_safe( reasons[i], (strlen( reasons[i] ) + 1) );
01011   }
01012 
01013   fprintf( ofile, "\n" );
01014 
01015   /* Deallocate memory */
01016   if( arc_size > 0 ) {
01017     free_safe( from_states, (sizeof( char* ) * arc_size) );
01018     free_safe( to_states, (sizeof( char* ) * arc_size) );
01019     free_safe( ids, (sizeof( int ) * arc_size) );
01020     free_safe( excludes, (sizeof( int ) * arc_size) );
01021     free_safe( reasons, (sizeof( char* ) * arc_size) );
01022   }
01023   free_safe( eid, eid_size );
01024 
01025   PROFILE_END;
01026 
01027   return( retval );
01028 
01029 }

static bool fsm_display_funit_summary ( FILE *  ofile,
const char *  name,
const char *  fname,
int  state_hits,
int  state_total,
int  arc_hits,
int  arc_total 
) [static]
Returns:
Returns TRUE if at least one FSM state or FSM arc was missed during simulation for this functional unit; otherwise, returns FALSE.

Outputs the summary FSM state/arc information for a given functional unit to the given output stream.

Parameters:
ofile Pointer to file stream to output summary information to
name Name of functional unit being reported
fname Filename containing the functional unit being reported
state_hits Number of FSM states that were hit in this functional unit during simulation
state_total Number of total FSM states that exist in the given functional unit
arc_hits Number of FSM arcs that were hit in this functional unit during simulation
arc_total Number of total FSM arcs that exist in the given functional unit

References calc_miss_percent(), PROFILE, and PROFILE_END.

Referenced by fsm_funit_summary(), and fsm_report().

00767   { PROFILE(FSM_DISPLAY_FUNIT_SUMMARY);
00768 
00769   float state_percent;  /* Percentage of states hit */
00770   float arc_percent;    /* Percentage of arcs hit */
00771   int   state_miss;     /* Number of states missed */
00772   int   arc_miss;       /* Number of arcs missed */
00773 
00774   if( (state_total == -1) || (arc_total == -1) ) {
00775     fprintf( ofile, "  %-20.20s    %-20.20s   %4d/  ? /  ?        ? %%         %4d/  ? /  ?        ? %%\n",
00776              name, fname, state_hits, arc_hits );
00777     state_miss = arc_miss = 1;
00778   } else {
00779     calc_miss_percent( state_hits, state_total, &state_miss, &state_percent );
00780     calc_miss_percent( arc_hits, arc_total, &arc_miss, &arc_percent );
00781     fprintf( ofile, "  %-20.20s    %-20.20s   %4d/%4d/%4d      %3.0f%%         %4d/%4d/%4d      %3.0f%%\n",
00782              name, fname, state_hits, state_miss, state_total, state_percent, arc_hits, arc_miss, arc_total, arc_percent );
00783   }
00784 
00785   PROFILE_END;
00786 
00787   return( (state_miss > 0) || (arc_miss > 0) );
00788 
00789 }

static bool fsm_display_instance_summary ( FILE *  ofile,
const char *  name,
int  state_hit,
int  state_total,
int  arc_hit,
int  arc_total 
) [static]
Returns:
Returns TRUE if at least one FSM state or FSM state transition was found to be missed

Calculates and displays the FSM state and state transition instance summary information for the given instance.

Parameters:
ofile Pointer to output file to write data to
name Name of instance to display
state_hit Number of FSM states hit in the given instance
state_total Total number of FSM states in the given instance
arc_hit Number of FSM state transitions in the given instance
arc_total Total number of FSM state transitions in the given instance

References calc_miss_percent(), PROFILE, and PROFILE_END.

Referenced by fsm_instance_summary(), and fsm_report().

00655   { PROFILE(FSM_DISPLAY_INSTANCE_SUMMARY);
00656 
00657   float state_percent;  /* Percentage of states hit */
00658   float arc_percent;    /* Percentage of arcs hit */
00659   int   state_miss;     /* Number of states missed */
00660   int   arc_miss;       /* Number of arcs missed */
00661 
00662   if( (state_total == -1) || (arc_total == -1) ) {
00663     fprintf( ofile, "  %-43.43s    %4d/  ? /  ?        ? %%         %4d/  ? /  ?        ? %%\n",
00664              name, state_hit, arc_hit );
00665     state_miss = arc_miss = 1;
00666   } else {
00667     calc_miss_percent( state_hit, state_total, &state_miss, &state_percent );
00668     calc_miss_percent( arc_hit, arc_total, &arc_miss, &arc_percent );
00669     fprintf( ofile, "  %-43.43s    %4d/%4d/%4d      %3.0f%%         %4d/%4d/%4d      %3.0f%%\n",
00670              name, state_hit, state_miss, state_total, state_percent, arc_hit, arc_miss, arc_total, arc_percent );
00671   }
00672 
00673   PROFILE_END;
00674 
00675   return( (state_miss > 0) || (arc_miss > 0) );
00676 
00677 }

static void fsm_display_state_verbose ( FILE *  ofile,
fsm table 
) [static]

Displays verbose information for hit/missed states to the specified output file.

Parameters:
ofile File handle of output file to send report output to
table Pointer to FSM structure to output

References arc_get_states(), FALSE, free_safe, fsm_s::from_state, fsuppl_u::known, fsuppl_u::part, PROFILE, PROFILE_END, report_covered, fsm_table_s::suppl, fsm_s::table, fsm_s::to_state, expression_s::value, and vector_s::width.

Referenced by fsm_display_verbose().

00856   { PROFILE(FSM_DISPLAY_STATE_VERBOSE);
00857 
00858   bool         trans_unknown;  /* Set to TRUE if legal arc transitions are unknown */
00859   char**       fr_states;      /* String array of all from states */
00860   unsigned int fr_state_size;  /* Contains the number of elements in the fr_states array */
00861   char**       to_states;      /* String array of all to states */
00862   unsigned int to_state_size;  /* Contains the number of elements in the to_states array */
00863   unsigned int i;              /* Loop iterator */
00864 
00865   /* Figure out if transitions were unknown */
00866   trans_unknown = (table->table->suppl.part.known == 0);
00867 
00868   if( report_covered || trans_unknown ) {
00869     fprintf( ofile, "        Hit States\n\n" );
00870   } else {
00871     fprintf( ofile, "        Missed States\n\n" );
00872   }
00873 
00874   /* Create format string */
00875   fprintf( ofile, "          States\n" );
00876   fprintf( ofile, "          ======\n" );
00877 
00878   /* Get all of the states in string form */
00879   arc_get_states( &fr_states, &fr_state_size, &to_states, &to_state_size, table->table, (report_covered || trans_unknown), FALSE,
00880                   table->from_state->value->width, table->to_state->value->width );
00881 
00882   /* Display all of the found states */
00883   for( i=0; i<fr_state_size; i++ ) {
00884     fprintf( ofile, "          %s\n", fr_states[i] );
00885     free_safe( fr_states[i], (strlen( fr_states[i] ) + 1) );
00886   }
00887 
00888   fprintf( ofile, "\n" );
00889 
00890   /* Deallocate the states array */
00891   if( fr_state_size > 0 ) {
00892     free_safe( fr_states, (sizeof( char* ) * fr_state_size) );
00893   }
00894   if( to_state_size > 0 ) {
00895     for( i=0; i<to_state_size; i++ ) {
00896       free_safe( to_states[i], (strlen( to_states[i] ) + 1) );
00897     }
00898     free_safe( to_states, (sizeof( char* ) * to_state_size) );
00899   }
00900 
00901   PROFILE_END;
00902 
00903 }

static void fsm_display_verbose ( FILE *  ofile,
func_unit funit 
) [static]

Displays the verbose FSM state and state transition information to the specified output file.

Parameters:
ofile File handle of output file to send report output to
funit Pointer to functional unit containing the FSMs to display

References codegen_gen_expr(), free_safe, fsm_s::from_state, fsm_display_arc_verbose(), fsm_display_state_verbose(), func_unit_s::fsm_head, expression_s::id, fsm_link_s::next, expression_s::op, PROFILE, PROFILE_END, report_covered, report_exclusions, RPT_TYPE_EXCL, RPT_TYPE_HIT, RPT_TYPE_MISS, fsm_link_s::table, and fsm_s::to_state.

Referenced by fsm_funit_verbose(), and fsm_instance_verbose().

01038   { PROFILE(FSM_DISPLAY_VERBOSE);
01039 
01040   fsm_link*    head;         /* Pointer to current FSM link */
01041   char**       icode;        /* Verilog output of input state variable expression */
01042   unsigned int icode_depth;  /* Number of valid entries in the icode array */
01043   char**       ocode;        /* Verilog output of output state variable expression */
01044   unsigned int ocode_depth;  /* Number of valid entries in the ocode array */
01045   unsigned int i;            /* Loop iterator */
01046 
01047   head = funit->fsm_head;
01048   while( head != NULL ) {
01049 
01050     bool found_exclusion;
01051 
01052     if( head->table->from_state->id == head->table->to_state->id ) {
01053       codegen_gen_expr( head->table->to_state, head->table->to_state->op, &ocode, &ocode_depth, NULL );
01054       fprintf( ofile, "      FSM input/output state (%s)\n\n", ocode[0] );
01055       for( i=0; i<ocode_depth; i++ ) {
01056         free_safe( ocode[i], (strlen( ocode[i] ) + 1) );
01057       }
01058       free_safe( ocode, (sizeof( char* ) * ocode_depth) );
01059     } else {
01060       codegen_gen_expr( head->table->from_state, head->table->from_state->op, &icode, &icode_depth, NULL );
01061       codegen_gen_expr( head->table->to_state,   head->table->to_state->op,   &ocode, &ocode_depth, NULL );
01062       fprintf( ofile, "      FSM input state (%s), output state (%s)\n\n", icode[0], ocode[0] );
01063       for( i=0; i<icode_depth; i++ ) {
01064         free_safe( icode[i], (strlen( icode[i] ) + 1) );
01065       }
01066       free_safe( icode, (sizeof( char* ) * icode_depth) );
01067       for( i=0; i<ocode_depth; i++ ) {
01068         free_safe( ocode[i], (strlen( ocode[i] ) + 1) );
01069       }
01070       free_safe( ocode, (sizeof( char* ) * ocode_depth) );
01071     }
01072 
01073     fsm_display_state_verbose( ofile, head->table );
01074     found_exclusion = fsm_display_arc_verbose( ofile, head->table, funit, (report_covered ? RPT_TYPE_HIT : RPT_TYPE_MISS) );
01075     if( report_exclusions && found_exclusion ) {
01076       (void)fsm_display_arc_verbose( ofile, head->table, funit, RPT_TYPE_EXCL );
01077     }
01078 
01079     if( head->next != NULL ) {
01080       fprintf( ofile, "      - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n" );
01081     }
01082 
01083     head = head->next;
01084 
01085   }
01086 
01087   PROFILE_END;
01088 
01089 }

static bool fsm_funit_summary ( FILE *  ofile,
funit_link head,
int *  state_hits,
int *  state_total,
int *  arc_hits,
int *  arc_total 
) [static]
Returns:
Returns TRUE if any FSM states/arcs were found missing; otherwise, returns FALSE.

Generates a functional unit summary report of the current FSM states and arcs hit during simulation.

Parameters:
ofile Pointer to output file to display report contents to
head Pointer to functional unit list to traverse
state_hits Pointer to number of states that were hit in all functional units
state_total Pointer to total number of states found in all functional units
arc_hits Pointer to number of state transitions found in all functional units
arc_total Pointer to total number of state transitions found in all functional units

References statistic_s::arc_hit, statistic_s::arc_total, isuppl_u::assert_ovl, FALSE, func_unit_s::filename, free_safe, fsm_display_funit_summary(), funit_link_s::funit, funit_flatten_name(), funit_is_unnamed(), get_basename(), funit_link_s::next, obf_file, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, scope_gen_printable(), statistic_s::show, func_unit_s::stat, statistic_s::state_hit, and statistic_s::state_total.

Referenced by fsm_report().

00803   { PROFILE(FSM_FUNIT_SUMMARY);
00804 
00805   bool  miss_found = FALSE;  /* Set to TRUE if state/arc was found to be missed */
00806   char* pname;               /* Printable version of functional unit name */
00807 
00808   while( head != NULL ) {
00809 
00810     /* If this is an assertion module, don't output any further */
00811     if( head->funit->stat->show && !funit_is_unnamed( head->funit ) &&
00812         ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( head->funit )) ) {
00813 
00814       /* Get printable version of functional unit name */
00815       pname = scope_gen_printable( funit_flatten_name( head->funit ) );
00816 
00817       miss_found |= fsm_display_funit_summary( ofile, pname, get_basename( obf_file( head->funit->filename ) ),
00818                                                head->funit->stat->state_hit, head->funit->stat->state_total,
00819                                                head->funit->stat->arc_hit, head->funit->stat->arc_total );
00820 
00821       /* Update accumulated information */
00822       *state_hits += head->funit->stat->state_hit;
00823       if( (head->funit->stat->state_total == -1) || (*state_total == -1) ) {
00824         *state_total = -1;
00825       } else {
00826         *state_total += head->funit->stat->state_total;
00827       }
00828       *arc_hits += head->funit->stat->arc_hit;
00829       if( (head->funit->stat->arc_total == -1) || (*arc_total == -1) ) {
00830         *arc_total = -1;
00831       } else {
00832         *arc_total += head->funit->stat->arc_total;
00833       }
00834 
00835       free_safe( pname, (strlen( pname ) + 1) );
00836 
00837     }
00838 
00839     head = head->next;
00840 
00841   }
00842 
00843   PROFILE_END;
00844 
00845   return( miss_found );
00846 
00847 }

static void fsm_funit_verbose ( FILE *  ofile,
funit_link head 
) [static]

Generates a functional unit verbose report of the current FSM states and arcs hit during simulation.

Parameters:
ofile Pointer to output file to display report contents to
head Pointer to head of functional unit list to traverse

References statistic_s::arc_excluded, statistic_s::arc_hit, statistic_s::arc_total, func_unit_s::filename, free_safe, fsm_display_verbose(), funit_link_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, funit_link_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, scope_gen_printable(), func_unit_s::stat, statistic_s::state_hit, statistic_s::state_total, and func_unit_s::type.

Referenced by fsm_report().

01166   { PROFILE(FSM_FUNIT_VERBOSE);
01167 
01168   char* pname;  /* Printable version of functional unit name */
01169 
01170   while( head != NULL ) {
01171 
01172     if( !funit_is_unnamed( head->funit ) &&
01173         ((((head->funit->stat->state_hit < head->funit->stat->state_total) || 
01174            (head->funit->stat->arc_hit < head->funit->stat->arc_total)) && !report_covered) ||
01175            (head->funit->stat->state_total == -1) ||
01176            (head->funit->stat->arc_total   == -1) ||
01177          (((head->funit->stat->state_hit > 0) || (head->funit->stat->arc_hit > 0)) && report_covered) ||
01178          ((head->funit->stat->arc_excluded > 0) && report_exclusions)) ) {
01179 
01180       /* Get printable version of functional unit name */
01181       pname = scope_gen_printable( funit_flatten_name( head->funit ) );
01182 
01183       fprintf( ofile, "\n" );
01184       switch( head->funit->type ) {
01185         case FUNIT_MODULE       :  fprintf( ofile, "    Module: " );       break;
01186         case FUNIT_ANAMED_BLOCK :
01187         case FUNIT_NAMED_BLOCK  :  fprintf( ofile, "    Named Block: " );  break;
01188         case FUNIT_AFUNCTION    :
01189         case FUNIT_FUNCTION     :  fprintf( ofile, "    Function: " );     break;
01190         case FUNIT_ATASK        :
01191         case FUNIT_TASK         :  fprintf( ofile, "    Task: " );         break;
01192         default                 :  fprintf( ofile, "    UNKNOWN: " );      break;
01193       }
01194       fprintf( ofile, "%s, File: %s\n", pname, obf_file( head->funit->filename ) );
01195       fprintf( ofile, "    -------------------------------------------------------------------------------------------------------------\n" );
01196 
01197       free_safe( pname, (strlen( pname ) + 1) );
01198 
01199       fsm_display_verbose( ofile, head->funit );
01200 
01201     }
01202 
01203     head = head->next;
01204 
01205   }
01206 
01207   PROFILE_END;
01208 
01209 }

static void fsm_gather_signals ( expression expr,
sig_link **  head,
sig_link **  tail,
int  expr_id,
int **  expr_ids,
int *  expr_id_size 
) [static]

Recursively iterates through specified expression, adding the signal of each expression that points to one to the specified signal list. Also captures the expression ID of the statement containing this signal for each signal found (if expr_id is a non-negative value).

Parameters:
expr Pointer to expression to get signals from
head Pointer to head of signal list to populate
tail Pointer to tail of signal list to populate
expr_id Expression ID of the statement containing this expression
expr_ids Pointer to expression ID array
expr_id_size Number of elements currently stored in expr_ids array

References expression_s::left, PROFILE, PROFILE_END, realloc_safe, expression_s::right, expression_s::sig, and sig_link_add().

Referenced by fsm_collect().

00482   { PROFILE(FSM_GATHER_SIGNALS);
00483 
00484   if( expr != NULL ) {
00485 
00486     if( expr->sig != NULL ) {
00487 
00488       /* Add this signal to the list */
00489       sig_link_add( expr->sig, head, tail );
00490 
00491       /* Add specified expression ID to the expression IDs array, if needed */
00492       if( expr_id >= 0 ) {
00493         (*expr_ids)                  = (int*)realloc_safe( *expr_ids, (sizeof( int ) * (*expr_id_size)), (sizeof( int ) * ((*expr_id_size) + 1)) );
00494         (*expr_ids)[(*expr_id_size)] = expr_id;
00495         (*expr_id_size)++;
00496       }
00497 
00498     } else {
00499 
00500       fsm_gather_signals( expr->left,  head, tail, expr_id, expr_ids, expr_id_size );
00501       fsm_gather_signals( expr->right, head, tail, expr_id, expr_ids, expr_id_size );
00502 
00503     }
00504 
00505   }
00506 
00507   PROFILE_END;
00508 
00509 }

void fsm_get_coverage ( func_unit funit,
int  expr_id,
char ***  total_fr_states,
unsigned int *  total_fr_state_num,
char ***  total_to_states,
unsigned int *  total_to_state_num,
char ***  hit_fr_states,
unsigned int *  hit_fr_state_num,
char ***  hit_to_states,
unsigned int *  hit_to_state_num,
char ***  total_from_arcs,
char ***  total_to_arcs,
int **  total_ids,
int **  excludes,
char ***  reasons,
int *  total_arc_num,
char ***  hit_from_arcs,
char ***  hit_to_arcs,
int *  hit_arc_num,
char ***  input_state,
unsigned int *  input_size,
char ***  output_state,
unsigned int *  output_size 
)

Collects all coverage information for the specified FSM.

Gets the FSM coverage information for the specified FSM in the specified functional unit. Used by the GUI for creating the contents of the verbose FSM viewer.

Parameters:
funit Pointer to functional unit
expr_id Expression ID of output state expression to find
total_fr_states Pointer to a string array containing all possible from states in this FSM
total_fr_state_num Pointer to the number of elements in the total_fr_states array
total_to_states Pointer to a string array containing all possible to states in this FSM
total_to_state_num Pointer to the number of elements in the total_to_states array
hit_fr_states Pointer to a string array containing the hit fr_states in this FSM
hit_fr_state_num Pointer to the number of elements in the hit_fr_states array
hit_to_states Pointer to a string array containing the hit to_states in this FSM
hit_to_state_num Pointer to the number of elements in the hit_to_states array
total_from_arcs Pointer to a string array containing all possible state transition from states
total_to_arcs Pointer to a string array containing all possible state transition to states
total_ids Pointer to an integer array containing the arc transition IDs for each transition
excludes Pointer to an integer array containing the exclude values for each state transition
reasons Pointer to a string array containing exclusion reasons
total_arc_num Pointer to the number of elements in both the total_from_arcs, total_to_arcs and excludes arrays
hit_from_arcs Pointer to a string array containing the hit state transition from states
hit_to_arcs Pointer to a string array containing the hit state transition to states
hit_arc_num Pointer to the number of elements in both the hit_from_arcs and hit_to_arcs arrays
input_state Pointer to a string array containing the code for the input state expression
input_size Pointer to the number of elements stored in the input state array
output_state Pointer to a string array containing the code for the output state expression
output_size Pointer to the number of elements stored in the output state array

References arc_get_states(), arc_get_transitions(), codegen_gen_expr(), FALSE, free_safe, fsm_s::from_state, func_unit_s::fsm_head, expression_s::id, fsm_link_s::next, expression_s::op, PROFILE, PROFILE_END, fsm_s::table, fsm_link_s::table, fsm_s::to_state, TRUE, expression_s::value, and vector_s::width.

00594   { PROFILE(FSM_GET_COVERAGE);
00595 
00596   fsm_link*    curr_fsm;
00597   int*         tmp_ids;
00598   int*         tmp;
00599   char**       tmp_reasons;
00600   unsigned int fr_width;
00601   unsigned int to_width;
00602 
00603   curr_fsm = funit->fsm_head;
00604   while( (curr_fsm != NULL) && (curr_fsm->table->to_state->id != expr_id) ) {
00605     curr_fsm = curr_fsm->next; 
00606   }
00607 
00608   assert( curr_fsm != NULL );
00609 
00610   fr_width = curr_fsm->table->from_state->value->width;
00611   to_width = curr_fsm->table->to_state->value->width;
00612 
00613   /* Get state information */
00614   arc_get_states( total_fr_states, total_fr_state_num, total_to_states, total_to_state_num, curr_fsm->table->table, TRUE, TRUE,  fr_width, to_width ); 
00615   arc_get_states( hit_fr_states,   hit_fr_state_num,   hit_to_states,   hit_to_state_num,   curr_fsm->table->table, TRUE, FALSE, fr_width, to_width );
00616 
00617   /* Get state transition information */
00618   arc_get_transitions( total_from_arcs, total_to_arcs, total_ids, excludes, reasons,      total_arc_num, curr_fsm->table->table, funit, TRUE, TRUE,  fr_width, to_width );
00619   arc_get_transitions( hit_from_arcs,   hit_to_arcs,   &tmp_ids,  &tmp,     &tmp_reasons, hit_arc_num,   curr_fsm->table->table, funit, TRUE, FALSE, fr_width, to_width );
00620 
00621   /* Get input state code */
00622   codegen_gen_expr( curr_fsm->table->from_state, curr_fsm->table->from_state->op, input_state, input_size, NULL );
00623 
00624   /* Get output state code */
00625   codegen_gen_expr( curr_fsm->table->to_state, curr_fsm->table->to_state->op, output_state, output_size, NULL );
00626 
00627   /* Deallocate unused state information */
00628   if( *hit_arc_num > 0 ) {
00629     unsigned int i;
00630     free_safe( tmp_ids, (sizeof( int ) * (*hit_arc_num)) );
00631     free_safe( tmp,     (sizeof( int ) * (*hit_arc_num)) );
00632     for( i=0; i<(*hit_arc_num); i++ ) {
00633       free_safe( tmp_reasons[i], (strlen( tmp_reasons[i] ) + 1) );
00634     }
00635     free_safe( tmp_reasons, (sizeof( char* ) * (*hit_arc_num)) );
00636   }
00637 
00638   PROFILE_END;
00639 
00640 }

void fsm_get_funit_summary ( func_unit funit,
int *  hit,
int *  excluded,
int *  total 
)

Retrieves the FSM summary information for the specified functional unit.

Parameters:
funit Pointer to functional unit
hit Pointer to location to store the number of hit state transitions for the specified functional unit
excluded Pointer to number of excluded arcs
total Pointer to location to store the total number of state transitions for the specified functional unit

References statistic_s::arc_excluded, statistic_s::arc_hit, statistic_s::arc_total, PROFILE, PROFILE_END, and func_unit_s::stat.

00442   { PROFILE(FSM_GET_FUNIT_SUMMARY);
00443 
00444   *hit      = funit->stat->arc_hit;
00445   *excluded = funit->stat->arc_excluded;
00446   *total    = funit->stat->arc_total;
00447 
00448   PROFILE_END;
00449 
00450 }

void fsm_get_inst_summary ( funit_inst inst,
int *  hit,
int *  excluded,
int *  total 
)

Retrieves the FSM summary information for the specified functional unit.

Retrieves the FSM summary information for the specified functional unit instance.

Parameters:
inst Pointer to functional unit instance
hit Pointer to location to store the number of hit state transitions for the specified functional unit
excluded Pointer to number of excluded arcs
total Pointer to location to store the total number of state transitions for the specified functional unit

References statistic_s::arc_excluded, statistic_s::arc_hit, statistic_s::arc_total, PROFILE, PROFILE_END, and funit_inst_s::stat.

00460   { PROFILE(FSM_GET_INST_SUMMARY);
00461 
00462   *hit      = inst->stat->arc_hit;
00463   *excluded = inst->stat->arc_excluded;
00464   *total    = inst->stat->arc_total;
00465 
00466   PROFILE_END;
00467 
00468 }

void fsm_get_stats ( fsm_link table,
int *  state_hit,
int *  state_total,
int *  arc_hit,
int *  arc_total,
int *  arc_excluded 
)

Gathers statistics about the current FSM.

Gathers the FSM state and state transition statistics for the given table and assigns this information to the specified pointers.

Parameters:
table Pointer to FSM to get statistics from
state_hit Number of states reached in this FSM
state_total Total number of states within this FSM
arc_hit Number of arcs reached in this FSM
arc_total Total number of arcs within this FSM
arc_excluded Total number of excluded arcs

References arc_get_stats(), fsm_link_s::next, PROFILE, PROFILE_END, fsm_s::table, and fsm_link_s::table.

Referenced by report_gather_funit_stats(), and report_gather_instance_stats().

00420   { PROFILE(FSM_GET_STATS);
00421 
00422   fsm_link* curr;   /* Pointer to current FSM in table list */
00423 
00424   curr = table;
00425   while( curr != NULL ) {
00426     arc_get_stats( curr->table->table, state_hit, state_total, arc_hit, arc_total, arc_excluded );
00427     curr = curr->next;
00428   }
00429 
00430   PROFILE_END;
00431 
00432 }

static bool fsm_instance_summary ( FILE *  ofile,
funit_inst root,
char *  parent_inst,
int *  state_hits,
int *  state_total,
int *  arc_hits,
int *  arc_total 
) [static]
Returns:
Returns TRUE if any FSM states/arcs were found missing; otherwise, returns FALSE.

Generates an instance summary report of the current FSM states and arcs hit during simulation.

Parameters:
ofile Pointer to output file to display report contents to
root Pointer to current root of instance tree to report
parent_inst String containing Verilog hierarchy of this instance's parent
state_hits Pointer to total number of states hit in design
state_total Pointer to total number of states in design
arc_hits Pointer to total number of arcs traversed
arc_total Pointer to total number of arcs in design

References statistic_s::arc_hit, statistic_s::arc_total, isuppl_u::assert_ovl, funit_inst_s::child_head, db_is_unnamed_scope(), FALSE, free_safe, fsm_display_instance_summary(), funit_inst_s::funit, funit_is_unnamed(), funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, ovl_is_assertion_module(), isuppl_u::part, PROFILE, PROFILE_END, scope_gen_printable(), statistic_s::show, funit_inst_s::stat, statistic_s::state_hit, statistic_s::state_total, and funit_inst_s::suppl.

Referenced by fsm_report().

00692   { PROFILE(FSM_INSTANCE_SUMMARY);
00693 
00694   funit_inst* curr;                /* Pointer to current child functional unit instance of this node */
00695   char        tmpname[4096];       /* Temporary name holder for instance */
00696   char*       pname;               /* Printable version of instance name */
00697   bool        miss_found = FALSE;  /* Set to TRUE if at least state or arc was not hit */
00698 
00699   assert( root != NULL );
00700   assert( root->stat != NULL );
00701 
00702   /* Generate printable version of instance name */
00703   pname = scope_gen_printable( root->name );
00704 
00705   if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) {
00706     strcpy( tmpname, parent_inst );
00707   } else if( strcmp( parent_inst, "*" ) == 0 ) {
00708     strcpy( tmpname, pname );
00709   } else {
00710     unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent_inst, pname ); 
00711     assert( rv < 4096 );
00712   }
00713 
00714   free_safe( pname, (strlen( pname ) + 1) );
00715 
00716   if( (root->funit != NULL) && root->stat->show && !funit_is_unnamed( root->funit ) &&
00717       ((info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit )) ) {
00718 
00719     miss_found |= fsm_display_instance_summary( ofile, tmpname, root->stat->state_hit, root->stat->state_total, root->stat->arc_hit, root->stat->arc_total );
00720 
00721     /* Update accumulated information */
00722     *state_hits += root->stat->state_hit; 
00723     if( (root->stat->state_total == -1) || (*state_total == -1) ) {
00724       *state_total = -1;
00725     } else {
00726       *state_total += root->stat->state_total;
00727     }
00728     *arc_hits += root->stat->arc_hit;
00729     if( (root->stat->arc_total == -1) || (*arc_total == -1) ) {
00730       *arc_total = -1;
00731     } else {
00732       *arc_total += root->stat->arc_total;
00733     }
00734 
00735   }
00736 
00737   /* If this is an assertion module, don't output any further */
00738   if( (info_suppl.part.assert_ovl == 0) || !ovl_is_assertion_module( root->funit ) ) {
00739 
00740     curr = root->child_head;
00741     while( curr != NULL ) {
00742       miss_found |= fsm_instance_summary( ofile, curr, tmpname, state_hits, state_total, arc_hits, arc_total );
00743       curr = curr->next;
00744     }
00745 
00746   }
00747 
00748   PROFILE_END;
00749 
00750   return( miss_found );
00751 
00752 }

static void fsm_instance_verbose ( FILE *  ofile,
funit_inst root,
char *  parent_inst 
) [static]

Generates an instance verbose report of the current FSM states and arcs hit during simulation.

Parameters:
ofile Pointer to output file to display report contents to
root Pointer to root of instance tree to traverse
parent_inst String containing name of this instance's parent instance

References statistic_s::arc_excluded, statistic_s::arc_hit, statistic_s::arc_total, funit_inst_s::child_head, db_is_unnamed_scope(), func_unit_s::filename, free_safe, fsm_display_verbose(), funit_inst_s::funit, FUNIT_AFUNCTION, FUNIT_ANAMED_BLOCK, FUNIT_ATASK, funit_flatten_name(), FUNIT_FUNCTION, funit_is_unnamed(), FUNIT_MODULE, FUNIT_NAMED_BLOCK, FUNIT_TASK, funit_inst_s::name, funit_inst_s::name_diff, funit_inst_s::next, obf_file, PROFILE, PROFILE_END, report_covered, report_exclusions, scope_gen_printable(), funit_inst_s::stat, statistic_s::state_hit, statistic_s::state_total, funit_inst_s::suppl, and func_unit_s::type.

Referenced by fsm_report().

01098   { PROFILE(FSM_INSTANCE_VERBOSE);
01099 
01100   funit_inst* curr_inst;      /* Pointer to current instance being evaluated */
01101   char        tmpname[4096];  /* Temporary name holder for instance */
01102   char*       pname;          /* Printable version of instance name */
01103 
01104   assert( root != NULL );
01105 
01106   /* Get printable version of instance name */
01107   pname = scope_gen_printable( root->name );
01108 
01109   if( db_is_unnamed_scope( pname ) || root->suppl.name_diff ) {
01110     strcpy( tmpname, parent_inst );
01111   } else if( strcmp( parent_inst, "*" ) == 0 ) {
01112     strcpy( tmpname, pname );
01113   } else {
01114     unsigned int rv = snprintf( tmpname, 4096, "%s.%s", parent_inst, pname );
01115     assert( rv < 4096 );
01116   }
01117 
01118   free_safe( pname, (strlen( pname ) + 1) );
01119 
01120   if( (root->funit != NULL) && !funit_is_unnamed( root->funit ) &&
01121       ((((root->stat->state_hit < root->stat->state_total) || (root->stat->arc_hit < root->stat->arc_total)) && !report_covered) ||
01122          (root->stat->state_total == -1) ||
01123          (root->stat->arc_total   == -1) ||
01124        (((root->stat->state_hit > 0) || (root->stat->arc_hit > 0)) && report_covered) ||
01125        ((root->stat->arc_excluded > 0) && report_exclusions)) ) {
01126 
01127     /* Get printable version of functional unit name */
01128     pname = scope_gen_printable( funit_flatten_name( root->funit ) );
01129 
01130     fprintf( ofile, "\n" );
01131     switch( root->funit->type ) {
01132       case FUNIT_MODULE       :  fprintf( ofile, "    Module: " );       break;
01133       case FUNIT_ANAMED_BLOCK :
01134       case FUNIT_NAMED_BLOCK  :  fprintf( ofile, "    Named Block: " );  break;
01135       case FUNIT_AFUNCTION    :
01136       case FUNIT_FUNCTION     :  fprintf( ofile, "    Function: " );     break;
01137       case FUNIT_ATASK        :
01138       case FUNIT_TASK         :  fprintf( ofile, "    Task: " );         break;
01139       default                 :  fprintf( ofile, "    UNKNOWN: " );      break;
01140     }
01141     fprintf( ofile, "%s, File: %s, Instance: %s\n", pname, obf_file( root->funit->filename ), tmpname );
01142     fprintf( ofile, "    -------------------------------------------------------------------------------------------------------------\n" );
01143 
01144     free_safe( pname, (strlen( pname ) + 1) );
01145 
01146     fsm_display_verbose( ofile, root->funit );
01147 
01148   }
01149 
01150   curr_inst = root->child_head;
01151   while( curr_inst != NULL ) {
01152     fsm_instance_verbose( ofile, curr_inst, tmpname );
01153     curr_inst = curr_inst->next;
01154   }
01155 
01156   PROFILE_END;
01157 
01158 }

void fsm_merge ( fsm base,
fsm other 
)

Merges two FSMs, placing the result into the base FSM.

Merges two FSMs, placing the resulting FSM into the base. This function is called when merging modules for the GUI.

Parameters:
base Base FSM to store merged results
other Other FSM that will be merged with the base FSM

References arc_merge(), fsm_s::from_state, PROFILE, PROFILE_END, fsm_s::table, and fsm_s::to_state.

Referenced by funit_merge().

00359   { PROFILE(FSM_MERGE);
00360 
00361   assert( base != NULL );
00362   assert( base->from_state != NULL );
00363   assert( base->to_state != NULL );
00364   assert( other != NULL );
00365   assert( other->from_state != NULL );
00366   assert( other->to_state != NULL );
00367 
00368   if( base->table != NULL ) {
00369     assert( other->table != NULL );
00370     arc_merge( base->table, other->table );
00371   }
00372 
00373   PROFILE_END;
00374 
00375 }

void fsm_report ( FILE *  ofile,
bool  verbose 
)

Generates report output for FSM coverage.

After the design is read into the functional unit hierarchy, parses the hierarchy by functional unit, reporting the FSM coverage for each functional unit encountered. The parent functional unit will specify its own FSM coverage along with a total FSM coverage including its children.

Parameters:
ofile Pointer to file to output results to
verbose Specifies whether or not to provide verbose information

References curr_db, FALSE, fsm_display_funit_summary(), fsm_display_instance_summary(), fsm_funit_summary(), fsm_funit_verbose(), fsm_instance_summary(), fsm_instance_verbose(), funit_head, inst_link_s::inst, db_s::inst_head, funit_inst_s::name_diff, inst_link_s::next, PROFILE, PROFILE_END, report_covered, report_exclusions, report_instance, and funit_inst_s::suppl.

Referenced by report_generate().

01220   { PROFILE(FSM_REPORT);
01221 
01222   bool       missed_found  = FALSE;  /* If set to TRUE, FSM cases were found to be missed */
01223   inst_link* instl;                  /* Pointer to current instance link */
01224   int        acc_st_hits   = 0;      /* Accumulated number of states hit */
01225   int        acc_st_total  = 0;      /* Accumulated number of states in design */
01226   int        acc_arc_hits  = 0;      /* Accumulated number of arcs hit */
01227   int        acc_arc_total = 0;      /* Accumulated number of arcs in design */
01228 
01229   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
01230   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   FINITE STATE MACHINE COVERAGE RESULTS   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
01231   fprintf( ofile, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" );
01232 
01233   if( report_instance ) {
01234 
01235     fprintf( ofile, "                                                               State                             Arc\n" );
01236     fprintf( ofile, "Instance                                          Hit/Miss/Total    Percent hit    Hit/Miss/Total    Percent hit\n" );
01237     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01238 
01239     instl = db_list[curr_db]->inst_head;
01240     while( instl != NULL ) {
01241       missed_found |= fsm_instance_summary( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*"), &acc_st_hits, &acc_st_total, &acc_arc_hits, &acc_arc_total );
01242       instl = instl->next;
01243     }
01244     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01245     (void)fsm_display_instance_summary( ofile, "Accumulated", acc_st_hits, acc_st_total, acc_arc_hits, acc_arc_total );
01246    
01247     if( verbose && (missed_found || report_covered || report_exclusions) ) {
01248       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01249       instl = db_list[curr_db]->inst_head;
01250       while( instl != NULL ) {
01251         fsm_instance_verbose( ofile, instl->inst, (instl->inst->suppl.name_diff ? "<NA>" : "*") );
01252         instl = instl->next;
01253       }
01254     }
01255 
01256   } else {
01257 
01258     fprintf( ofile, "                                                               State                             Arc\n" );
01259     fprintf( ofile, "Module/Task/Function      Filename                Hit/Miss/Total    Percent Hit    Hit/Miss/Total    Percent hit\n" );
01260     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01261 
01262     missed_found = fsm_funit_summary( ofile, db_list[curr_db]->funit_head, &acc_st_hits, &acc_st_total, &acc_arc_hits, &acc_arc_total );
01263     fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01264     (void)fsm_display_funit_summary( ofile, "Accumulated", "", acc_st_hits, acc_st_total, acc_arc_hits, acc_arc_total );
01265 
01266     if( verbose && (missed_found || report_covered || report_exclusions) ) {
01267       fprintf( ofile, "---------------------------------------------------------------------------------------------------------------------\n" );
01268       fsm_funit_verbose( ofile, db_list[curr_db]->funit_head );
01269     }
01270 
01271   }
01272 
01273   fprintf( ofile, "\n\n" );
01274 
01275   PROFILE_END;
01276 
01277 }

void fsm_table_set ( expression expr,
const sim_time time 
)

Sets the bit in set table based on the values of last and curr.

Taking the from and to state signal values, a new table entry is added to the specified FSM structure arc array (if an entry does not already exist in the array).

Parameters:
expr Pointer to expression that contains FSM table to modify
time Pointer to current simulation time

References arc_add(), fsm_s::exclude, fsm_s::from_state, expression_s::id, PROFILE, PROFILE_END, sim_expr_changed(), fsm_s::table, expression_s::table, fsm_s::to_state, expression_s::value, and vector_copy().

Referenced by expression_operate().

00385   { PROFILE(FSM_TABLE_SET);
00386 
00387   /* If the expression is the input state expression, make sure that the output state expression is simulated this clock period */
00388   if( (expr->table->from_state->id == expr->id) && (expr->table->from_state->id != expr->table->to_state->id) ) {
00389 
00390     sim_expr_changed( expr->table->to_state, time );
00391 
00392   /* Otherwise, add the state/state transition */
00393   } else {
00394 
00395     /* Add the states and state transition */
00396     arc_add( expr->table->table, expr->table->from_state->value, expr->table->to_state->value, 1, expr->table->exclude );
00397 
00398     /* If from_state was not specified, we need to copy the current contents of to_state to from_state */
00399     if( expr->table->from_state->id == expr->id ) {
00400       vector_copy( expr->value, expr->table->from_state->value );
00401     }
00402 
00403   }
00404 
00405   PROFILE_END;
00406 
00407 }


Variable Documentation

unsigned int curr_db

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

Array of database pointers storing all currently loaded databases.

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

Informational line for the CDD file.

unsigned int report_comb_depth

If set to a non-zero value, causes Covered to only generate combinational logic report information for depths up to the number specified.

If set to a boolean value of TRUE, displays covered logic for a particular CDD file. By default, Covered will display uncovered logic. Must be used in conjunction with the -d v|d (verbose output) option.

If set to a boolean value of TRUE, displays excluded coverage points for a particular CDD file. By default, Covered will not display excluded coverage points. This can be useful when used in conjunction with the -x option for including excluded coverage points. Must be used in conjunction with the -d v|d (verbose output) option.

If set to a boolean value of TRUE, provides a coverage information for individual functional unit instances. If set to a value of FALSE, reports coverage information on a functional unit basis, merging results from all instances of same functional unit.

char user_msg[USER_MSG_LENGTH]

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

Generated on Sun Nov 21 00:55:38 2010 for Covered by  doxygen 1.6.3