vsignal.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "defines.h"
#include "expr.h"
#include "func_unit.h"
#include "link.h"
#include "obfuscate.h"
#include "sim.h"
#include "util.h"
#include "vector.h"
#include "vsignal.h"

Functions

static void vsignal_init (vsignal *sig, char *name, unsigned int type, vector *value, unsigned int line, unsigned int col)
vsignalvsignal_create (const char *name, unsigned int type, unsigned int width, unsigned int line, unsigned int col)
 Creates a new vsignal based on the information passed to this function.
void vsignal_create_vec (vsignal *sig)
 Creates the vector for a given signal based on the values of its dimension information.
vsignalvsignal_duplicate (vsignal *sig)
 Duplicates the given signal and returns a newly allocated signal.
void vsignal_db_write (vsignal *sig, FILE *file)
 Outputs this vsignal information to specified file.
void vsignal_db_read (char **line, func_unit *curr_funit)
 Reads vsignal information from specified file.
void vsignal_db_merge (vsignal *base, char **line, bool same)
 Reads and merges two vsignals, placing result into base vsignal.
void vsignal_merge (vsignal *base, vsignal *other)
 Merges two vsignals, placing the result into the base vsignal.
void vsignal_propagate (vsignal *sig, const sim_time *time)
 Propagates specified signal information to rest of design.
void vsignal_vcd_assign (vsignal *sig, const char *value, unsigned int msb, unsigned int lsb, const sim_time *time)
 Assigns specified VCD value to specified vsignal.
void vsignal_add_expression (vsignal *sig, expression *expr)
 Adds an expression to the vsignal list.
void vsignal_display (vsignal *sig)
 Displays vsignal contents to standard output.
vsignalvsignal_from_string (char **str)
 Converts a string to a vsignal.
int vsignal_calc_width_for_expr (expression *expr, vsignal *sig)
 Calculates width of the specified signal's vector value based on the given expression.
int vsignal_calc_lsb_for_expr (expression *expr, vsignal *sig, int lsb_val)
 Calculates LSB of the specified signal's vector value based on the given expression.
void vsignal_dealloc (vsignal *sig)
 Deallocates the memory used for this vsignal.

Variables

char user_msg [USER_MSG_LENGTH]
bool debug_mode

Detailed Description

Author:
Trevor Williams (phase1geo@gmail.com)
Date:
12/1/2001

Function Documentation

void vsignal_add_expression ( vsignal sig,
expression expr 
)

Adds an expression to the vsignal list.

Adds the specified expression to the end of this vsignal's expression list.

Parameters:
sig Pointer to vsignal to add expression to
expr Expression to add to list

References vsignal_s::exp_head, exp_link_add(), vsignal_s::exp_tail, PROFILE, and PROFILE_END.

00572   { PROFILE(VSIGNAL_ADD_EXPRESSION);
00573 
00574   exp_link_add( expr, &(sig->exp_head), &(sig->exp_tail) );
00575 
00576   PROFILE_END;
00577 
00578 }

int vsignal_calc_lsb_for_expr ( expression expr,
vsignal sig,
int  lsb_val 
)

Calculates LSB of the specified signal's vector value based on the given expression.

Returns:
Returns the LSB of the given signal for the given expression.
Parameters:
expr Pointer to expression to get LSB for
sig Pointer to signal to get LSB for
lsb_val Calculated LSB value from this expression

References PROFILE, PROFILE_END, and vsignal_calc_width_for_expr().

00738   { PROFILE(VSIGNAL_CALC_LSB_FOR_EXPR);
00739 
00740   int width = vsignal_calc_width_for_expr( expr, sig ) * lsb_val;
00741 
00742   PROFILE_END;
00743 
00744   return( width );
00745 
00746 }

int vsignal_calc_width_for_expr ( expression expr,
vsignal sig 
)

Calculates width of the specified signal's vector value based on the given expression.

Parameters:
expr Pointer to expression to get width for
sig Pointer to signal to get width for
Returns:
Returns width of the given expression that is bound to the given signal.

References vsignal_s::dim, expression_get_curr_dimension(), dim_range_s::lsb, dim_range_s::msb, vsignal_s::pdim_num, PROFILE, PROFILE_END, and vsignal_s::udim_num.

Referenced by expression_set_value(), race_check_one_block_assignment(), and vsignal_calc_lsb_for_expr().

00704   { PROFILE(VSIGNAL_CALC_WIDTH_FOR_EXPR);
00705 
00706   int          exp_dim;    /* Expression dimension number */
00707   int          width = 1;  /* Return value for this function */
00708   unsigned int i;          /* Loop iterator */
00709 
00710   assert( expr != NULL );
00711   assert( sig != NULL );
00712 
00713   /* Get expression dimension value */
00714   exp_dim = expression_get_curr_dimension( expr );
00715 
00716   /* Calculate width */
00717   for( i=(exp_dim + 1); i < (sig->pdim_num + sig->udim_num); i++ ) {
00718     if( sig->dim[i].msb > sig->dim[i].lsb ) {
00719       width *= (sig->dim[i].msb - sig->dim[i].lsb) + 1;
00720     } else {
00721       width *= (sig->dim[i].lsb - sig->dim[i].msb) + 1;
00722     }
00723   }
00724 
00725   PROFILE_END;
00726 
00727   return( width );
00728 
00729 }

vsignal* vsignal_create ( const char *  name,
unsigned int  type,
unsigned int  width,
unsigned int  line,
unsigned int  col 
)

Creates a new vsignal based on the information passed to this function.

Returns:
Pointer to newly created vsignal.

This function should be called by the Verilog parser or the database reading function. It initializes all of the necessary values for a vsignal and returns a pointer to this newly created vsignal.

Parameters:
name Full hierarchical name of this vsignal
type Type of signal to create
width Bit width of this vsignal
line Line number that this signal is declared on
col Starting column that this signal is declared on

References malloc_safe, PROFILE, PROFILE_END, SSUPPL_TYPE_DECL_REAL, SSUPPL_TYPE_DECL_SREAL, SSUPPL_TYPE_IMPLICIT_REAL, SSUPPL_TYPE_IMPLICIT_SREAL, SSUPPL_TYPE_MEM, SSUPPL_TYPE_PARAM_REAL, strdup_safe, TRUE, VDATA_R32, VDATA_R64, VDATA_UL, vector_create(), vsignal_init(), VTYPE_MEM, and VTYPE_SIG.

Referenced by bind_signal(), db_add_signal(), inst_parm_add(), vsignal_db_read(), and vsignal_from_string().

00094   { PROFILE(VSIGNAL_CREATE);
00095 
00096   vsignal*     new_sig;  /* Pointer to newly created vsignal */
00097   unsigned int vtype;
00098 
00099   new_sig = (vsignal*)malloc_safe( sizeof( vsignal ) );
00100 
00101   /* Calculate the type */
00102   switch( type ) {
00103     case SSUPPL_TYPE_DECL_REAL      :
00104     case SSUPPL_TYPE_PARAM_REAL     :
00105     case SSUPPL_TYPE_IMPLICIT_REAL  :  vtype = VDATA_R64;  break;
00106     case SSUPPL_TYPE_DECL_SREAL     :
00107     case SSUPPL_TYPE_IMPLICIT_SREAL :  vtype = VDATA_R32;  break;
00108     default                         :  vtype = VDATA_UL;   break;
00109   }
00110 
00111   vsignal_init( new_sig, ((name != NULL) ? strdup_safe( name ) : NULL),
00112                 type, vector_create( width, ((type == SSUPPL_TYPE_MEM) ? VTYPE_MEM : VTYPE_SIG), vtype, TRUE ), line, col );
00113 
00114   PROFILE_END;
00115 
00116   return( new_sig );
00117 
00118 }

void vsignal_create_vec ( vsignal sig  ) 

Creates the vector for a given signal based on the values of its dimension information.

Exceptions:
anonymous expression_set_value

Calculates the signal width and creates a vector value that is sized to match this width. This function is called during race condition checking and functional unit element sizing function and needs to be called before expression resizing is performed.

Parameters:
sig Pointer to signal to create vector for

References ssuppl_u::big_endian, vsignal_s::dim, exp_link_s::exp, vsignal_s::exp_head, EXP_OP_FUNC_CALL, EXP_OP_PASSIGN, expression_set_value(), free_safe, dim_range_s::lsb, dim_range_s::msb, exp_link_s::next, expression_s::op, ssuppl_u::part, vsuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, vsuppl_u::set, SSUPPL_TYPE_DECL_REAL, SSUPPL_TYPE_DECL_SREAL, SSUPPL_TYPE_IMPLICIT_REAL, SSUPPL_TYPE_IMPLICIT_SREAL, SSUPPL_TYPE_MEM, SSUPPL_TYPE_PARAM_REAL, vsignal_s::suppl, vector_s::suppl, TRUE, ssuppl_u::type, vsignal_s::udim_num, vector_s::ul, vector_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_create(), vector_dealloc_value(), VTYPE_MEM, VTYPE_SIG, and vector_s::width.

Referenced by funit_size_elements(), and gen_item_resize_stmts_and_sigs().

00129   { PROFILE(VSIGNAL_CREATE_VEC);
00130 
00131   unsigned int i;     /* Loop iterator */
00132   vector*      vec;   /* Temporary vector used for getting a vector value */
00133   exp_link*    expl;  /* Pointer to current expression in signal expression list */
00134 
00135   assert( sig != NULL );
00136   assert( sig->value != NULL );
00137 
00138   /* If this signal has been previously simulated, don't create a new vector */
00139   if( !sig->value->suppl.part.set ) {
00140 
00141     unsigned int vtype;
00142 
00143     /* Deallocate the old memory */
00144     vector_dealloc_value( sig->value );
00145 
00146     /* Set the initial signal width to 1 */
00147     sig->value->width = 1;
00148 
00149     /* Calculate the width of the given signal */
00150     for( i=0; i<(sig->pdim_num + sig->udim_num); i++ ) {
00151       if( sig->dim[i].msb > sig->dim[i].lsb ) {
00152         sig->value->width *= ((sig->dim[i].msb - sig->dim[i].lsb) + 1);
00153       } else {
00154         sig->value->width *= ((sig->dim[i].lsb - sig->dim[i].msb) + 1);
00155       }
00156     }
00157 
00158     /* Set the endianness */
00159     if( (sig->pdim_num + sig->udim_num) > 0 ) {
00160       sig->suppl.part.big_endian = (sig->dim[(sig->pdim_num + sig->udim_num)-1].msb < sig->dim[(sig->pdim_num + sig->udim_num)-1].lsb) ? 1 : 0;
00161     }
00162 
00163     /* Figure out the vector data type to create */
00164     switch( sig->suppl.part.type ) {
00165       case SSUPPL_TYPE_DECL_REAL      :
00166       case SSUPPL_TYPE_PARAM_REAL     :
00167       case SSUPPL_TYPE_IMPLICIT_REAL  :  vtype = VDATA_R64;  break;
00168       case SSUPPL_TYPE_DECL_SREAL     :
00169       case SSUPPL_TYPE_IMPLICIT_SREAL :  vtype = VDATA_R32;  break;
00170       default                         :  vtype = VDATA_UL;   break;
00171     }
00172 
00173     /* Create the vector and assign it to the signal */
00174     vec = vector_create( sig->value->width, ((sig->suppl.part.type == SSUPPL_TYPE_MEM) ? VTYPE_MEM : VTYPE_SIG), vtype, TRUE );
00175     sig->value->value.ul = vec->value.ul;
00176     free_safe( vec, sizeof( vector ) );
00177 
00178     /* Iterate through expression list, setting the expression to this signal */
00179     expl = sig->exp_head;
00180     while( expl != NULL ) {
00181       if( (expl->exp->op != EXP_OP_FUNC_CALL) && (expl->exp->op != EXP_OP_PASSIGN) ) {
00182         expression_set_value( expl->exp, sig, NULL );
00183       }
00184       expl = expl->next;
00185     }
00186 
00187   }
00188 
00189   PROFILE_END;
00190 
00191 }

void vsignal_db_merge ( vsignal base,
char **  line,
bool  same 
)

Reads and merges two vsignals, placing result into base vsignal.

Exceptions:
anonymous vector_db_merge Throw Throw

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

Parameters:
base Signal to store result of merge into
line Pointer to line of CDD file to parse
same Specifies if vsignal to merge needs to be exactly the same as the existing vsignal

References ssuppl_u::all, ssuppl_u::excluded, FATAL, vsignal_s::name, ssuppl_u::part, vsignal_s::pdim_num, print_output(), PROFILE, PROFILE_END, scope_compare(), vsignal_s::suppl, Throw, vsignal_s::udim_num, vsignal_s::value, and vector_db_merge().

Referenced by funit_db_inst_merge(), and funit_db_mod_merge().

00390   { PROFILE(VSIGNAL_DB_MERGE);
00391  
00392   char         name[256];   /* Name of current vsignal */
00393   int          id;          /* Unique ID of current signal */
00394   int          sline;       /* Declared line number */
00395   unsigned int pdim_num;    /* Number of packed dimensions */
00396   unsigned int udim_num;    /* Number of unpacked dimensions */
00397   int          msb;         /* MSB of current dimension being read */
00398   int          lsb;         /* LSB of current dimension being read */
00399   ssuppl       suppl;       /* Supplemental signal information */
00400   int          chars_read;  /* Number of characters read from line */
00401   unsigned int i;           /* Loop iterator */
00402 
00403   assert( base != NULL );
00404   assert( base->name != NULL );
00405 
00406   if( sscanf( *line, "%s %d %d %x %u %u%n", name, &id, &sline, &(suppl.all), &pdim_num, &udim_num, &chars_read ) == 6 ) {
00407 
00408     *line = *line + chars_read;
00409 
00410     if( !scope_compare( base->name, name ) || (base->pdim_num != pdim_num) || (base->udim_num != udim_num) ) {
00411 
00412       print_output( "Attempting to merge two databases derived from different designs.  Unable to merge",
00413                     FATAL, __FILE__, __LINE__ );
00414       Throw 0;
00415 
00416     } else {
00417 
00418       /* Make sure that the exclude bit is merged */
00419       base->suppl.part.excluded |= suppl.part.excluded;
00420 
00421       i = 0;
00422       while( (i < (pdim_num + udim_num)) && (sscanf( *line, " %d %d%n", &msb, &lsb, &chars_read ) == 2) ) {
00423         *line = *line + chars_read;
00424         i++;
00425       }
00426 
00427       if( i == (pdim_num + udim_num) ) {
00428 
00429         /* Read in vector information */
00430         vector_db_merge( base->value, line, same );
00431 
00432       }
00433 
00434     }
00435 
00436   } else {
00437 
00438     print_output( "Unable to parse vsignal in database file.  Unable to merge.", FATAL, __FILE__, __LINE__ );
00439     Throw 0;
00440 
00441   }
00442 
00443   PROFILE_END;
00444 
00445 }

void vsignal_db_read ( char **  line,
func_unit curr_funit 
)

Reads vsignal information from specified file.

Exceptions:
anonymous Throw Throw Throw vector_db_read

Creates a new vsignal structure, parses current file line for vsignal information and stores it to the specified vsignal. If there are any problems in reading in the current line, returns FALSE; otherwise, returns TRUE.

Parameters:
line Pointer to current line from database file to parse
curr_funit Pointer to current functional unit instantiating this vsignal

References ssuppl_u::all, ssuppl_u::assigned, ssuppl_u::big_endian, Catch_anonymous, ssuppl_u::col, vsignal_s::dim, ssuppl_u::excluded, FATAL, free_safe, vsignal_s::id, dim_range_s::lsb, malloc_safe, ssuppl_u::mba, ssuppl_u::part, vsignal_s::pdim_num, print_output(), PROFILE, PROFILE_END, func_unit_s::sig_head, sig_link_add(), func_unit_s::sig_tail, vsignal_s::suppl, Throw, Try, ssuppl_u::type, vsignal_s::udim_num, vsignal_s::value, vector_db_read(), vector_dealloc(), vsignal_create(), and vector_s::width.

Referenced by db_read(), and funit_db_mod_merge().

00298   { PROFILE(VSIGNAL_DB_READ);
00299 
00300   char         name[256];      /* Name of current vsignal */
00301   vsignal*     sig;            /* Pointer to the newly created vsignal */
00302   vector*      vec;            /* Vector value for this vsignal */
00303   int          id;             /* Signal ID */
00304   int          sline;          /* Declared line number */
00305   unsigned int pdim_num;       /* Packed dimension number */
00306   unsigned int udim_num;       /* Unpacked dimension number */
00307   dim_range*   dim    = NULL;  /* Dimensional information */
00308   ssuppl       suppl;          /* Supplemental field */
00309   int          chars_read;     /* Number of characters read from line */
00310   unsigned int i;              /* Loop iterator */
00311 
00312   /* Get name values. */
00313   if( sscanf( *line, "%s %d %d %x %u %u%n", name, &id, &sline, &(suppl.all), &pdim_num, &udim_num, &chars_read ) == 6 ) {
00314 
00315     *line = *line + chars_read;
00316 
00317     /* Allocate dimensional information */
00318     dim = (dim_range*)malloc_safe( sizeof( dim_range ) * (pdim_num + udim_num) );
00319 
00320     Try {
00321 
00322       /* Read in dimensional information */
00323       i = 0;
00324       while( i < (pdim_num + udim_num) ) {
00325         if( sscanf( *line, " %d %d%n", &(dim[i].msb), &(dim[i].lsb), &chars_read ) == 2 ) {
00326           *line = *line + chars_read;
00327         } else {
00328           print_output( "Unable to parse signal line in database file.  Unable to read.", FATAL, __FILE__, __LINE__ );
00329           Throw 0;
00330         }
00331         i++;
00332       }
00333 
00334       /* Read in vector information */
00335       vector_db_read( &vec, line );
00336 
00337     } Catch_anonymous {
00338       free_safe( dim, sizeof( dim_range ) );
00339       Throw 0;
00340     }
00341 
00342     /* Create new vsignal */
00343     sig = vsignal_create( name, suppl.part.type, vec->width, sline, suppl.part.col );
00344     sig->id                    = id;
00345     sig->suppl.part.assigned   = suppl.part.assigned;
00346     sig->suppl.part.mba        = suppl.part.mba;
00347     sig->suppl.part.big_endian = suppl.part.big_endian;
00348     sig->suppl.part.excluded   = suppl.part.excluded;
00349     sig->pdim_num              = pdim_num;
00350     sig->udim_num              = udim_num;
00351     sig->dim                   = dim;
00352 
00353     /* Copy over vector value */
00354     vector_dealloc( sig->value );
00355     sig->value = vec;
00356 
00357     /* Add vsignal to vsignal list */
00358     if( curr_funit == NULL ) {
00359       print_output( "Internal error:  vsignal in database written before its functional unit", FATAL, __FILE__, __LINE__ );
00360       Throw 0;
00361     } else {
00362       sig_link_add( sig, &(curr_funit->sig_head), &(curr_funit->sig_tail) );
00363     }
00364 
00365   } else {
00366 
00367     print_output( "Unable to parse signal line in database file.  Unable to read.", FATAL, __FILE__, __LINE__ );
00368     Throw 0;
00369 
00370   }
00371 
00372   PROFILE_END;
00373 
00374 }

void vsignal_db_write ( vsignal sig,
FILE *  file 
)

Outputs this vsignal information to specified file.

Prints the vsignal information for the specified vsignal to the specified file. This file will be the database coverage file for this design.

Parameters:
sig Signal to write to file
file Name of file to display vsignal contents to

References ssuppl_u::all, DB_TYPE_SIGNAL, vsignal_s::dim, vsignal_s::id, vsignal_s::line, dim_range_s::lsb, MAX_BIT_WIDTH, dim_range_s::msb, vsignal_s::name, ssuppl_u::not_handled, ssuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, SIGNAL_IS_NET, SSUPPL_TYPE_ENUM, SSUPPL_TYPE_GENVAR, SSUPPL_TYPE_PARAM, SSUPPL_TYPE_PARAM_REAL, vsignal_s::suppl, ssuppl_u::type, vsignal_s::udim_num, vsignal_s::value, vector_db_write(), and vector_s::width.

Referenced by funit_db_write(), gen_item_db_write(), and param_db_write().

00251   { PROFILE(VSIGNAL_DB_WRITE);
00252 
00253   unsigned int i;  /* Loop iterator */
00254 
00255   /* Don't write this vsignal if it isn't usable by Covered */
00256   if( (sig->suppl.part.not_handled == 0) &&
00257       (sig->value->width != 0) &&
00258       (sig->value->width <= MAX_BIT_WIDTH) &&
00259       (sig->suppl.part.type != SSUPPL_TYPE_GENVAR) ) {
00260 
00261     /* Display identification and value information first */
00262     fprintf( file, "%d %s %d %d %x %u %u",
00263       DB_TYPE_SIGNAL,
00264       sig->name,
00265       sig->id,
00266       sig->line,
00267       sig->suppl.all,
00268       sig->pdim_num,
00269       sig->udim_num
00270     );
00271 
00272     /* Display dimension information */
00273     for( i=0; i<(sig->pdim_num + sig->udim_num); i++ ) {
00274       fprintf( file, " %d %d", sig->dim[i].msb, sig->dim[i].lsb );
00275     }
00276     fprintf( file, " " );
00277 
00278     vector_db_write( sig->value, file, ((sig->suppl.part.type == SSUPPL_TYPE_PARAM) || (sig->suppl.part.type == SSUPPL_TYPE_PARAM_REAL) || (sig->suppl.part.type == SSUPPL_TYPE_ENUM)), SIGNAL_IS_NET( sig ) );
00279 
00280     fprintf( file, "\n" );
00281 
00282   }
00283 
00284   PROFILE_END;
00285 
00286 }

void vsignal_dealloc ( vsignal sig  ) 

Deallocates the memory used for this vsignal.

Parameters:
sig Pointer to vsignal to deallocate.

Deallocates all malloc'ed memory back to the heap for the specified vsignal.

References vsignal_s::dim, exp_link_s::exp, vsignal_s::exp_head, exp_link_delete_list(), FALSE, free_safe, vsignal_s::name, exp_link_s::next, vsignal_s::pdim_num, PROFILE, PROFILE_END, expression_s::sig, vsignal_s::udim_num, vsignal_s::value, and vector_dealloc().

Referenced by fsm_arg_parse_state(), gen_item_dealloc(), inst_parm_dealloc(), sig_link_delete_list(), and struct_union_member_dealloc().

00756   { PROFILE(VSIGNAL_DEALLOC);
00757 
00758   exp_link* curr_expl;  /* Pointer to current expression link to set to NULL */
00759 
00760   if( sig != NULL ) {
00761 
00762     /* Free the signal name */
00763     free_safe( sig->name, (strlen( sig->name ) + 1) );
00764     sig->name = NULL;
00765 
00766     /* Free the dimension information */
00767     free_safe( sig->dim, (sizeof( dim_range ) * (sig->pdim_num + sig->udim_num)) );
00768 
00769     /* Free up memory for value */
00770     vector_dealloc( sig->value );
00771     sig->value = NULL;
00772 
00773     /* Free up memory for expression list */
00774     curr_expl = sig->exp_head;
00775     while( curr_expl != NULL ) {
00776       curr_expl->exp->sig = NULL;
00777       curr_expl = curr_expl->next;
00778     }
00779 
00780     exp_link_delete_list( sig->exp_head, FALSE );
00781     sig->exp_head = NULL;
00782 
00783     /* Finally free up the memory for this vsignal */
00784     free_safe( sig, sizeof( vsignal ) );
00785 
00786   }
00787 
00788   PROFILE_END;
00789 
00790 }

void vsignal_display ( vsignal sig  ) 

Displays vsignal contents to standard output.

Displays vsignal's name, dimensional info, width and value vector to the standard output.

Parameters:
sig Pointer to vsignal to display to standard output

References vsuppl_u::data_type, vsignal_s::dim, dim_range_s::lsb, dim_range_s::msb, vsignal_s::name, obf_sig, vsuppl_u::part, vsignal_s::pdim_num, vector_s::r32, vector_s::r64, vector_s::suppl, vsignal_s::udim_num, vector_s::ul, rv32_s::val, rv64_s::val, vector_s::value, vsignal_s::value, VDATA_R32, VDATA_R64, VDATA_UL, vector_display_value_ulong(), and vector_s::width.

Referenced by expression_assign(), expression_op_func__idec(), expression_op_func__iinc(), expression_op_func__pdec(), expression_op_func__pinc(), funit_display_signals(), mod_parm_display(), and sim_perform_nba().

00585   {
00586 
00587   unsigned int i;  /* Loop iterator */
00588 
00589   assert( sig != NULL );
00590 
00591   printf( "  Signal =>  name: %s, ", obf_sig( sig->name ) );
00592 
00593   if( sig->pdim_num > 0 ) {
00594     printf( "packed: " );
00595     for( i=sig->udim_num; i<(sig->pdim_num + sig->udim_num); i++ ) {
00596       printf( "[%d:%d]", sig->dim[i].msb, sig->dim[i].lsb );
00597     }
00598     printf( ", " );
00599   }
00600 
00601   if( sig->udim_num > 0 ) {
00602     printf( "unpacked: " );
00603     for( i=0; i<sig->udim_num; i++ ) {
00604       printf( "[%d:%d]", sig->dim[i].msb, sig->dim[i].lsb );
00605     }
00606     printf( ", " );
00607   }
00608 
00609   switch( sig->value->suppl.part.data_type ) {
00610     case VDATA_UL  :  vector_display_value_ulong( sig->value->value.ul, sig->value->width );  break;
00611     case VDATA_R64 :  printf( "%.16lf", sig->value->value.r64->val );  break;
00612     case VDATA_R32 :  printf( "%.16f", sig->value->value.r32->val );  break;
00613     default        :  assert( 0 );  break;
00614   }
00615 
00616   printf( "\n" );
00617 
00618 }

vsignal* vsignal_duplicate ( vsignal sig  ) 

Duplicates the given signal and returns a newly allocated signal.

Returns:
Returns a newly allocated and initialized copy of the given signal

Duplicates the contents of the given signal with the exception of the expression list.

Parameters:
sig Pointer to signal to duplicate

References ssuppl_u::all, vsignal_s::dim, exp_link_s::exp, vsignal_s::exp_head, exp_link_add(), vsignal_s::exp_tail, vsignal_s::line, dim_range_s::lsb, malloc_safe, dim_range_s::msb, vsignal_s::name, exp_link_s::next, vsignal_s::pdim_num, PROFILE, PROFILE_END, strdup_safe, vsignal_s::suppl, vsignal_s::udim_num, vsignal_s::value, and vector_clone().

Referenced by inst_parm_add_genvar().

00200   { PROFILE(VSIGNAL_DUPLICATE);
00201 
00202   vsignal*     new_sig;  /* Pointer to newly created vsignal */
00203   exp_link*    expl;     /* Pointer to current expression link */
00204   unsigned int i;        /* Loop iterator */
00205 
00206   assert( sig != NULL );
00207 
00208   new_sig = (vsignal*)malloc_safe( sizeof( vsignal ) );
00209   new_sig->name      = strdup_safe( sig->name );
00210   new_sig->suppl.all = sig->suppl.all;
00211   new_sig->pdim_num  = sig->pdim_num;
00212   new_sig->udim_num  = sig->udim_num;
00213   new_sig->dim       = NULL;
00214   new_sig->line      = sig->line;
00215   new_sig->exp_head  = NULL;
00216   new_sig->exp_tail  = NULL;
00217 
00218   /* Copy the dimension information */
00219   if( (sig->pdim_num + sig->udim_num) > 0 ) {
00220     new_sig->dim = (dim_range*)malloc_safe( sizeof( dim_range ) * (sig->pdim_num + sig->udim_num) );
00221     for( i=0; i<(sig->pdim_num + sig->udim_num); i++ ) {
00222       new_sig->dim[i].msb = sig->dim[i].msb;
00223       new_sig->dim[i].lsb = sig->dim[i].lsb;
00224     }
00225   }
00226 
00227   /* Copy the vector value */
00228   vector_clone( sig->value, &(new_sig->value) );
00229 
00230   /* Copy the expression pointers */
00231   expl = sig->exp_head;
00232   while( expl != NULL ) {
00233     exp_link_add( expl->exp, &(new_sig->exp_head), &(new_sig->exp_tail) );
00234     expl = expl->next;
00235   }
00236 
00237   PROFILE_END;
00238 
00239   return( new_sig );
00240 
00241 }

vsignal* vsignal_from_string ( char **  str  ) 

Converts a string to a vsignal.

Parameters:
str String version of vsignal.
Returns:
Returns pointer to newly created vsignal structure, or returns NULL is specified string does not properly describe a vsignal.

Converts the specified string describing a Verilog design vsignal. The vsignal may be a standard vsignal name, a single bit select vsignal or a multi-bit select vsignal.

References ssuppl_u::big_endian, vsignal_s::dim, dim_range_s::lsb, malloc_safe, dim_range_s::msb, ssuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, SSUPPL_TYPE_IMPLICIT, SSUPPL_TYPE_IMPLICIT_NEG, SSUPPL_TYPE_IMPLICIT_POS, vsignal_s::suppl, vector_s::ul, vector_s::value, vsignal_s::value, vector_dealloc_value(), vsignal_create(), and vector_s::width.

Referenced by fsm_arg_parse_state().

00632   { PROFILE(VSIGNAL_FROM_STRING);
00633 
00634   vsignal* sig;             /* Pointer to newly created vsignal */
00635   char     name[4096];      /* Signal name */
00636   int      left;            /* Left selection value of the signal */
00637   int      right;           /* Right selection value of the signal */
00638   int      width;           /* Width of the signal */
00639   int      big_endian = 0;  /* Endianness of the signal */
00640   int      chars_read;      /* Number of characters read from string */
00641 
00642   if( sscanf( *str, "%[a-zA-Z0-9_]\[%d:%d]%n", name, &left, &right, &chars_read ) == 3 ) {
00643     if( right > left ) {
00644       width      = (right - left) + 1;
00645       big_endian = 1;
00646     } else {
00647       width      = (left - right) + 1;
00648       big_endian = 0;
00649     }
00650     sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT, width, 0, 0 );
00651     sig->pdim_num   = 1;
00652     sig->dim        = (dim_range*)malloc_safe( sizeof( dim_range ) * 1 );
00653     sig->dim[0].msb = left;
00654     sig->dim[0].lsb = right;
00655     sig->suppl.part.big_endian = big_endian;
00656     *str += chars_read;
00657   } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d+:%d]%n", name, &left, &right, &chars_read ) == 3 ) {
00658     sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT_POS, right, 0, 0 );
00659     sig->pdim_num   = 1;
00660     sig->dim        = (dim_range*)malloc_safe( sizeof( dim_range ) * 1 );
00661     sig->dim[0].msb = left + right;
00662     sig->dim[0].lsb = left;
00663     *str += chars_read;
00664   } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d-:%d]%n", name, &left, &right, &chars_read ) == 3 ) {
00665     sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT_NEG, right, 0, 0 );
00666     sig->pdim_num   = 1;
00667     sig->dim        = (dim_range*)malloc_safe( sizeof( dim_range ) * 1 );
00668     sig->dim[0].msb = left - right;
00669     sig->dim[0].lsb = left;
00670     *str += chars_read;
00671   } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d]%n", name, &right, &chars_read ) == 2 ) {
00672     sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT, 1, 0, 0 );
00673     sig->pdim_num   = 1;
00674     sig->dim        = (dim_range*)malloc_safe( sizeof( dim_range ) * 1 );
00675     sig->dim[0].msb = right;
00676     sig->dim[0].lsb = right;
00677     *str += chars_read;
00678   } else if( sscanf( *str, "%[a-zA-Z0-9_]%n", name, &chars_read ) == 1 ) {
00679     sig = vsignal_create( name, SSUPPL_TYPE_IMPLICIT, 1, 0, 0 );
00680     /* Specify that this width is unknown */
00681     vector_dealloc_value( sig->value );
00682     sig->value->width = 0;
00683     sig->value->value.ul = NULL;
00684     *str += chars_read;
00685   } else {
00686     sig = NULL;
00687   }
00688 
00689   PROFILE_END;
00690 
00691   return( sig );
00692 
00693 }

static void vsignal_init ( vsignal sig,
char *  name,
unsigned int  type,
vector value,
unsigned int  line,
unsigned int  col 
) [static]

Initializes the specified vsignal with the values of name, value and lsb. This function is called by the vsignal_create routine and is also useful for creating temporary vsignals (reduces the need for dynamic memory allocation). for performance enhancing purposes.

Parameters:
sig Pointer to vsignal to initialize
name Pointer to vsignal name string
type Type of signal to create
value Pointer to vsignal value
line Line number that this signal is declared on
col Starting column that this signal is declared on

References ssuppl_u::all, ssuppl_u::col, vsignal_s::dim, vsignal_s::exp_head, vsignal_s::exp_tail, vsignal_s::id, vsignal_s::line, vsignal_s::name, ssuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, vsignal_s::suppl, ssuppl_u::type, vsignal_s::udim_num, and vsignal_s::value.

Referenced by vsignal_create().

00061   { PROFILE(VSIGNAL_INIT);
00062 
00063   sig->id              = 0;
00064   sig->name            = name;
00065   sig->pdim_num        = 0;
00066   sig->udim_num        = 0;
00067   sig->dim             = NULL;
00068   sig->suppl.all       = 0;
00069   sig->suppl.part.type = type;
00070   sig->suppl.part.col  = col;
00071   sig->value           = value;
00072   sig->line            = line;
00073   sig->exp_head        = NULL;
00074   sig->exp_tail        = NULL;
00075 
00076   PROFILE_END;
00077 
00078 }

void vsignal_merge ( vsignal base,
vsignal other 
)

Merges two vsignals, placing the result into the base vsignal.

Merges two vsignals, placing the result into the base vsignal. This function is used to calculate module coverage for the GUI.

Parameters:
base Base vsignal that will contain the merged results
other Other vsignal that will be merged into the base vsignal

References ssuppl_u::excluded, vsignal_s::name, ssuppl_u::part, vsignal_s::pdim_num, PROFILE, PROFILE_END, scope_compare(), vsignal_s::suppl, vsignal_s::udim_num, vsignal_s::value, and vector_merge().

Referenced by funit_merge().

00454   { PROFILE(VSIGNAL_MERGE);
00455 
00456   assert( base != NULL );
00457   assert( base->name != NULL );
00458   assert( scope_compare( base->name, other->name ) );
00459   //assert( base->id == other->id );
00460   assert( base->pdim_num == other->pdim_num );
00461   assert( base->udim_num == other->udim_num );
00462 
00463   /* Merge the exclusion information */
00464   base->suppl.part.excluded |= other->suppl.part.excluded;
00465 
00466   /* Read in vector information */
00467   vector_merge( base->value, other->value );
00468 
00469   PROFILE_END;
00470 
00471 }

void vsignal_propagate ( vsignal sig,
const sim_time time 
)

Propagates specified signal information to rest of design.

When the specified signal in the parameter list has changed values, this function is called to propagate the value change to the simulator to cause any statements waiting on this value change to be resimulated.

Parameters:
sig Pointer to signal to propagate change information from
time Current simulation time when signal changed

References exp_link_s::exp, vsignal_s::exp_head, EXP_OP_FUNC_CALL, EXP_OP_PASSIGN, exp_link_s::next, expression_s::op, PROFILE, PROFILE_END, and sim_expr_changed().

Referenced by expression_assign(), expression_op_func__add_a(), expression_op_func__assign(), expression_op_func__divide_a(), expression_op_func__idec(), expression_op_func__iinc(), expression_op_func__multiply_a(), expression_op_func__passign(), expression_op_func__pdec(), expression_op_func__pinc(), expression_op_func__sub_a(), expression_op_func__trigger(), expression_op_func__value_plusargs(), sim_perform_nba(), and vsignal_vcd_assign().

00481   { PROFILE(VSIGNAL_PROPAGATE);
00482 
00483   exp_link* curr_expr;  /* Pointer to current expression in signal list */
00484 
00485   /* Iterate through vsignal's expression list */
00486   curr_expr = sig->exp_head;
00487   while( curr_expr != NULL ) {
00488 
00489     /* Add to simulation queue if expression is a RHS, not a function call and not a port assignment */
00490     if( (curr_expr->exp->op != EXP_OP_FUNC_CALL) &&
00491         (curr_expr->exp->op != EXP_OP_PASSIGN) ) {
00492       sim_expr_changed( curr_expr->exp, time );
00493     }
00494 
00495     curr_expr = curr_expr->next;
00496 
00497   }
00498 
00499   PROFILE_END;
00500 
00501 }

void vsignal_vcd_assign ( vsignal sig,
const char *  value,
unsigned int  msb,
unsigned int  lsb,
const sim_time time 
)

Assigns specified VCD value to specified vsignal.

Exceptions:
anonymous vector_vcd_assign vector_vcd_assign

Assigns the associated value to the specified vsignal's vector. After this, it iterates through its expression list, setting the TRUE and FALSE bits accordingly. Finally, calls the simulator expr_changed function for each expression.

Parameters:
sig Pointer to vsignal to assign VCD value to
value String version of VCD value
msb Most significant bit to assign to
lsb Least significant bit to assign to
time Current simulation time signal is being assigned

References DEBUG, debug_mode, vsignal_s::dim, dim_range_s::lsb, vsignal_s::name, obf_sig, vsignal_s::pdim_num, print_output(), PROFILE, PROFILE_END, vsignal_s::udim_num, user_msg, USER_MSG_LENGTH, vsignal_s::value, vector_vcd_assign(), vsignal_propagate(), and vector_s::width.

Referenced by symtable_assign().

00516   { PROFILE(VSIGNAL_VCD_ASSIGN);
00517 
00518   bool vec_changed;  /* Specifies if assigned value differed from original value */
00519 
00520   assert( sig != NULL );
00521   assert( sig->value != NULL );
00522 
00523   /*
00524    Since this signal is coming from the dumpfile, we don't expect to see values for multi-dimensional
00525    arrays.
00526   */
00527   assert( sig->udim_num == 0 );
00528 
00529   /*
00530    VCS seems to create funny MSB values for packed arrays, so if the pdim_num is more than 1, adjust
00531    the MSB accordingly.
00532   */
00533   if( (sig->pdim_num > 1) && (msb >= sig->value->width) ) {
00534     msb = sig->value->width - 1;
00535   }
00536 
00537 #ifdef DEBUG_MODE
00538   if( debug_mode ) {
00539     unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Assigning vsignal %s[%d:%d] (lsb=%d) to value %s",
00540                                 obf_sig( sig->name ), msb, lsb, sig->dim[0].lsb, value );
00541     assert( rv < USER_MSG_LENGTH );
00542     print_output( user_msg, DEBUG, __FILE__, __LINE__ );
00543   }
00544 #endif
00545 
00546   /* Set vsignal value to specified value */
00547   if( lsb > 0 ) {
00548     vec_changed = vector_vcd_assign( sig->value, value, (msb - sig->dim[0].lsb), (lsb - sig->dim[0].lsb) );
00549   } else {
00550     vec_changed = vector_vcd_assign( sig->value, value, msb, lsb );
00551   }
00552 
00553   /* Don't go through the hassle of updating expressions if value hasn't changed */
00554   if( vec_changed ) {
00555 
00556     /* Propagate signal changes to rest of design */
00557     vsignal_propagate( sig, time );
00558 
00559   } 
00560 
00561   PROFILE_END;
00562 
00563 }


Variable Documentation

If set to TRUE, causes debug information to be spewed to screen.

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:42 2010 for Covered by  doxygen 1.6.3