Contains functions for handling Verilog signals. More...
#include <stdio.h>
#include "defines.h"
Go to the source code of this file.
Functions | |
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. | |
void | vsignal_create_vec (vsignal *sig) |
Creates the vector for a given signal based on the values of its dimension information. | |
vsignal * | vsignal_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. | |
vsignal * | vsignal_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. |
Contains functions for handling Verilog signals.
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.
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.
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.
expr | Pointer to expression to get width for | |
sig | Pointer to signal to get width for |
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.
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.
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.
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.
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 }
Reads and merges two vsignals, placing result into base vsignal.
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.
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.
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.
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.
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.
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.
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 }
Duplicates the given signal and returns a newly allocated signal.
Duplicates the contents of the given signal with the exception of the expression list.
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.
str | String version of 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 }
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.
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 }
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.
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.
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.
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 }