#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "vpi_user.h"
#include "binding.h"
#include "db.h"
#include "defines.h"
#include "instance.h"
#include "link.h"
#include "obfuscate.h"
#include "profiler.h"
#include "symtable.h"
#include "sys_tasks.h"
#include "util.h"
typedef struct sym_value_s sym_value |
Renaming sym_value_s structure for convenience.
void add_sym_values_to_sim | ( | ) |
Iterates through the sym_value list, adding the information to Covered's simulation core and deallocating its memory. Called by the covered_sim_calltf function.
References db_set_symbol_string(), free_safe, sym_value_s::next, PROFILE, PROFILE_END, sym_value_s::sym, and sym_value_s::value.
Referenced by covered_sim_calltf().
00151 { PROFILE(ADD_SYM_VALUES_TO_SIM); 00152 00153 sym_value* sval; /* Pointer to current sym_value structure */ 00154 00155 sval = sv_head; 00156 while( sv_head != NULL ) { 00157 00158 /* Assign the current sv_head to the sval pointer */ 00159 sval = sv_head; 00160 sv_head = sv_head->next; 00161 00162 /* Set the given symbol to the given value in Covered's simulator */ 00163 db_set_symbol_string( sval->sym, sval->value ); 00164 00165 /* Deallocate all memory associated with this sym_table structure */ 00166 free_safe( sval->sym, (strlen( sval->sym ) + 1) ); 00167 free_safe( sval->value, (strlen( sval->value ) + 1) ); 00168 free_safe( sval, sizeof( sym_value ) ); 00169 } 00170 00171 PROFILE_END; 00172 00173 }
PLI_INT32 covered_cb_error_handler | ( | p_cb_data | cb | ) |
References obf_file, PROFILE, and PROFILE_END.
Referenced by covered_sim_calltf().
00359 { PROFILE(COVERED_CB_ERROR_HANDLER); 00360 00361 struct t_vpi_error_info einfotab; 00362 struct t_vpi_error_info *einfop; 00363 char s1[128]; 00364 00365 einfop = &einfotab; 00366 vpi_chk_error( einfop ); 00367 00368 if( einfop->state == vpiCompile ) { 00369 strcpy( s1, "vpiCompile" ); 00370 } else if( einfop->state == vpiPLI ) { 00371 strcpy( s1, "vpiPLI" ); 00372 } else if( einfop->state == vpiRun ) { 00373 strcpy( s1, "vpiRun" ); 00374 } else { 00375 strcpy( s1, "**unknown**" ); 00376 } 00377 00378 vpi_printf( "covered VPI: ERR(%s) %s (level %d) at **%s(%d):\n %s\n", 00379 einfop->code, s1, einfop->level, obf_file( einfop->file ), einfop->line, einfop->message ); 00380 00381 /* If serious error give up */ 00382 if( (einfop->level == vpiError) || (einfop->level == vpiSystem) || (einfop->level == vpiInternal) ) { 00383 vpi_printf( "covered VPI: FATAL: encountered error - giving up\n" ); 00384 vpi_control( vpiFinish, 0 ); 00385 } 00386 00387 PROFILE_END; 00388 00389 return( 0 ); 00390 00391 }
void covered_create_value_change_cb | ( | vpiHandle | sig | ) |
Finds the given VPI signal in Covered's database and creates a callback function that will be called whenever this signal changes value during simulation. Also retrieves the initial value of the signal and stores it in the sym_value list and creates a symbol in the symtable structure for this signal.
sig | Pointer to vpiHandle for a given signal |
References ssuppl_u::assigned, covered_value_change_bin(), covered_value_change_real(), db_assign_symbol(), DEBUG, debug_mode, vsignal_s::dim, funit_inst_s::funit, gen_next_symbol(), dim_range_s::lsb, vsignal_s::name, obf_sig, ssuppl_u::part, print_output(), PROFILE, PROFILE_END, scope_find_signal(), sig_link_s::sig, func_unit_s::sig_head, sig_link_find(), vsignal_s::suppl, sym_value_store(), user_msg, USER_MSG_LENGTH, vsignal_s::value, and vector_s::width.
Referenced by covered_parse_signals(), and covered_parse_task_func().
00425 { PROFILE(COVERED_CREATE_VALUE_CHANGE_CB); 00426 00427 p_cb_data cb; 00428 sig_link* vsigl = NULL; 00429 vsignal* vsig = NULL; 00430 func_unit* found_funit; 00431 char* symbol; 00432 s_vpi_value value; 00433 00434 /* Only add the signal if it is in our database and needs to be assigned from the simulator */ 00435 if( (curr_instance->funit != NULL) && 00436 (((vsigl = sig_link_find( vpi_get_str( vpiName, sig ), curr_instance->funit->sig_head )) != NULL) || 00437 scope_find_signal( vpi_get_str( vpiName, sig ), curr_instance->funit, &vsig, &found_funit, 0 )) && 00438 (((vsigl != NULL) && (vsigl->sig->suppl.part.assigned == 0)) || 00439 ((vsig != NULL) && (vsig->suppl.part.assigned == 0))) ) { 00440 00441 if( vsigl != NULL ) { 00442 vsig = vsigl->sig; 00443 } 00444 00445 #ifdef DEBUG_MODE 00446 if( debug_mode ) { 00447 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Adding callback for signal: %s", obf_sig( vsig->name ) ); 00448 assert( rv < USER_MSG_LENGTH ); 00449 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00450 } 00451 #endif 00452 00453 /* Generate new symbol */ 00454 if( (symbol = gen_next_symbol()) == NULL ) { 00455 vpi_printf( "covered VPI: INTERNAL ERROR: Unable to generate unique symbol name\n" ); 00456 /* Need to increase number of characters in symbol array */ 00457 vpi_control( vpiFinish, 0 ); 00458 } 00459 00460 /* Add signal/symbol to symtab database */ 00461 db_assign_symbol( vpi_get_str( vpiName, sig ), symbol, ((vsig->value->width + vsig->dim[0].lsb) - 1), vsig->dim[0].lsb ); 00462 00463 /* Get initial value of this signal and store it for later retrieval */ 00464 if( vpi_get( vpiType, sig ) == vpiRealVar ) { 00465 00466 char real_str[64]; 00467 value.format = vpiRealVal; 00468 vpi_get_value( sig, &value ); 00469 snprintf( real_str, 64, "%f", value.value.real ); 00470 sym_value_store( symbol, real_str ); 00471 00472 } else { 00473 00474 value.format = vpiBinStrVal; 00475 vpi_get_value( sig, &value ); 00476 sym_value_store( symbol, value.value.str ); 00477 00478 } 00479 00480 /* Add a callback for a value change to this net */ 00481 cb = (p_cb_data)malloc( sizeof( s_cb_data ) ); 00482 cb->reason = cbValueChange; 00483 if( vpi_get( vpiType, sig ) == vpiRealVar ) { 00484 cb->cb_rtn = covered_value_change_real; 00485 } else { 00486 cb->cb_rtn = covered_value_change_bin; 00487 } 00488 cb->obj = sig; 00489 cb->time = (p_vpi_time)malloc( sizeof( s_vpi_time ) ); 00490 cb->time->type = vpiSimTime; 00491 cb->time->high = 0; 00492 cb->time->low = 0; 00493 #ifdef NOIV 00494 cb->value = (p_vpi_value)malloc( sizeof( s_vpi_value ) ); 00495 if( vpi_get( vpiType, sig ) == vpiRealVar ) { 00496 cb->value->format = vpiRealVal; 00497 } else { 00498 cb->value->format = vpiBinStrVal; 00499 cb->value->value.str = NULL; 00500 } 00501 #else 00502 cb->value = NULL; 00503 #endif 00504 cb->user_data = symbol; 00505 vpi_register_cb( cb ); 00506 00507 } 00508 00509 PROFILE_END; 00510 00511 }
PLI_INT32 covered_end_of_sim | ( | p_cb_data | cb | ) |
References Catch_anonymous, curr_inst_scope, curr_inst_scope_size, db_close(), db_do_timestep(), db_write(), FALSE, free_safe, last_time, malloc_safe, out_db_name, isuppl_u::part, PROFILE, PROFILE_END, isuppl_u::scored, sim_dealloc(), symtable_dealloc(), sys_task_dealloc(), TRUE, Try, and vcd_symtab_size.
Referenced by covered_sim_calltf().
00307 { PROFILE(COVERED_END_OF_SIM); 00308 00309 p_vpi_time final_time; 00310 00311 (void)db_do_timestep( last_time, FALSE ); 00312 00313 /* Get the final simulation time */ 00314 final_time = (p_vpi_time)malloc_safe( sizeof( s_vpi_time ) ); 00315 final_time->type = vpiSimTime; 00316 vpi_get_time( NULL, final_time ); 00317 00318 /* Flush any pending statement trees that are waiting for delay */ 00319 last_time = ((uint64)final_time->high << 32) | (uint64)final_time->low; 00320 (void)db_do_timestep( last_time, FALSE ); 00321 00322 /* Perform one last simulation timestep */ 00323 (void)db_do_timestep( 0, TRUE ); 00324 00325 /* Indicate that this CDD contains scored information */ 00326 info_suppl.part.scored = 1; 00327 00328 /* Write contents to database file */ 00329 Try { 00330 db_write( out_db_name, FALSE, FALSE ); 00331 vpi_printf( "covered VPI: Output coverage information to %s\n", out_db_name ); 00332 } Catch_anonymous { 00333 vpi_printf( "covered VPI: Unable to write database file\n" ); 00334 } 00335 00336 /* Deallocate memory */ 00337 if( curr_inst_scope_size > 0 ) { 00338 unsigned int i; 00339 for( i=0; i<curr_inst_scope_size; i++ ) { 00340 free_safe( curr_inst_scope[i], (strlen( curr_inst_scope[i] ) + 1) ); 00341 } 00342 free_safe( curr_inst_scope, sizeof( char* ) ); 00343 curr_inst_scope_size = 0; 00344 } 00345 symtable_dealloc( vcd_symtab ); 00346 sim_dealloc(); 00347 sys_task_dealloc(); 00348 db_close(); 00349 if( timestep_tab != NULL ) { 00350 free_safe( timestep_tab, (sizeof( symtable*) * vcd_symtab_size) ); 00351 } 00352 00353 PROFILE_END; 00354 00355 return( 0 ); 00356 00357 }
void covered_parse_instance | ( | vpiHandle | inst | ) |
References covered_parse_signals(), covered_parse_task_func(), curr_inst_scope, curr_inst_scope_size, db_sync_curr_instance(), DEBUG, debug_mode, free_safe, obf_funit, obf_inst, print_output(), PROFILE, PROFILE_END, strdup_safe, user_msg, and USER_MSG_LENGTH.
Referenced by covered_sim_calltf().
00680 { PROFILE(COVERED_PARSE_INSTANCE); 00681 00682 vpiHandle iter, handle; 00683 00684 /* Set current scope in database */ 00685 if( curr_inst_scope[0] != NULL ) { 00686 free_safe( curr_inst_scope[0], (strlen( curr_inst_scope[0] ) + 1) ); 00687 } 00688 curr_inst_scope[0] = strdup_safe( vpi_get_str( vpiFullName, inst ) ); 00689 curr_inst_scope_size = 1; 00690 00691 /* Synchronize curr_instance to point to curr_inst_scope */ 00692 db_sync_curr_instance(); 00693 00694 /* If current instance is known, parse this instance */ 00695 if( curr_instance != NULL ) { 00696 00697 #ifdef DEBUG_MODE 00698 if( debug_mode ) { 00699 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found module to be covered: %s, hierarchy: %s", 00700 obf_funit( vpi_get_str( vpiName, inst ) ), obf_inst( curr_inst_scope[0] ) ); 00701 assert( rv < USER_MSG_LENGTH ); 00702 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00703 } 00704 #endif 00705 00706 /* Parse all signals */ 00707 covered_parse_signals( inst ); 00708 00709 /* Parse all functions/tasks */ 00710 covered_parse_task_func( inst ); 00711 00712 } 00713 00714 /* Search children modules */ 00715 if( (iter = vpi_iterate( vpiModule, inst )) != NULL ) { 00716 00717 while( (handle = vpi_scan( iter )) != NULL ) { 00718 covered_parse_instance( handle ); 00719 } 00720 00721 } 00722 00723 PROFILE_END; 00724 00725 }
void covered_parse_signals | ( | vpiHandle | mod | ) |
References covered_create_value_change_cb(), DEBUG, debug_mode, obf_sig, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by covered_parse_instance().
00617 { PROFILE(COVERED_PARSE_SIGNALS); 00618 00619 vpiHandle iter, handle; 00620 int type; 00621 00622 /* Parse nets */ 00623 if( (iter = vpi_iterate( vpiNet, mod )) != NULL ) { 00624 while( (handle = vpi_scan( iter )) != NULL ) { 00625 #ifdef DEBUG_MODE 00626 if( debug_mode ) { 00627 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found net: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00628 assert( rv < USER_MSG_LENGTH ); 00629 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00630 } 00631 #endif 00632 covered_create_value_change_cb( handle ); 00633 } 00634 } 00635 00636 /* Parse regs */ 00637 if( (iter = vpi_iterate( vpiReg, mod )) != NULL ) { 00638 while( (handle = vpi_scan( iter )) != NULL ) { 00639 #ifdef DEBUG_MODE 00640 if( debug_mode ) { 00641 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found reg: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00642 assert( rv < USER_MSG_LENGTH ); 00643 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00644 } 00645 #endif 00646 covered_create_value_change_cb( handle ); 00647 } 00648 } 00649 00650 /* Parse integers */ 00651 if( (iter = vpi_iterate( vpiVariables, mod )) != NULL ) { 00652 while( (handle = vpi_scan( iter )) != NULL ) { 00653 type = vpi_get( vpiType, handle ); 00654 if( (type == vpiIntegerVar) || (type == vpiTimeVar) || (type == vpiReg) || (type == vpiRealVar) ) { 00655 #ifdef DEBUG_MODE 00656 if( debug_mode ) { 00657 unsigned int rv; 00658 if( type == vpiIntegerVar ) { 00659 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found integer: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00660 } else if( type == vpiTimeVar ) { 00661 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found time: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00662 } else if( type == vpiRealVar ) { 00663 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found real: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00664 } else if( type == vpiReg ) { 00665 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found reg: %s", obf_sig( vpi_get_str( vpiName, handle ) ) ); 00666 } 00667 assert( rv < USER_MSG_LENGTH ); 00668 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00669 } 00670 #endif 00671 covered_create_value_change_cb( handle ); 00672 } 00673 } 00674 } 00675 00676 PROFILE_END; 00677 00678 }
void covered_parse_task_func | ( | vpiHandle | mod | ) |
References covered_create_value_change_cb(), curr_inst_scope, curr_inst_scope_size, db_sync_curr_instance(), DEBUG, debug_mode, free_safe, obf_funit, obf_sig, print_output(), PROFILE, PROFILE_END, strdup_safe, user_msg, and USER_MSG_LENGTH.
Referenced by covered_parse_instance().
00513 { PROFILE(COVERED_PARSE_TASK_FUNC); 00514 00515 vpiHandle iter, handle; 00516 vpiHandle liter, scope; 00517 int type; 00518 00519 /* Parse all internal scopes for tasks and functions */ 00520 if( (iter = vpi_iterate( vpiInternalScope, mod )) != NULL ) { 00521 00522 while( (scope = vpi_scan( iter )) != NULL ) { 00523 00524 type = vpi_get( vpiType, scope ); 00525 00526 if( (type == vpiTask) || (type == vpiFunction) || (type == vpiNamedBegin) ) { 00527 00528 #ifdef DEBUG_MODE 00529 if( debug_mode ) { 00530 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Parsing task/function %s", obf_funit( vpi_get_str( vpiFullName, scope ) ) ); 00531 assert( rv < USER_MSG_LENGTH ); 00532 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00533 } 00534 #endif 00535 00536 /* Set current scope in database */ 00537 if( curr_inst_scope[0] != NULL ) { 00538 free_safe( curr_inst_scope[0], (strlen( curr_inst_scope[0] ) + 1) ); 00539 } 00540 curr_inst_scope[0] = strdup_safe( vpi_get_str( vpiFullName, scope ) ); 00541 curr_inst_scope_size = 1; 00542 00543 /* Synchronize curr_instance to point to curr_inst_scope */ 00544 db_sync_curr_instance(); 00545 00546 if( curr_instance != NULL ) { 00547 00548 /* Parse signals */ 00549 if( (liter = vpi_iterate( vpiNet, scope )) != NULL ) { 00550 while( (handle = vpi_scan( liter )) != NULL ) { 00551 #ifdef DEBUG_MODE 00552 if( debug_mode ) { 00553 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found net: %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00554 assert( rv < USER_MSG_LENGTH ); 00555 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00556 } 00557 #endif 00558 covered_create_value_change_cb( handle ); 00559 } 00560 } 00561 00562 if( (liter = vpi_iterate( vpiReg, scope )) != NULL ) { 00563 while( (handle = vpi_scan( liter )) != NULL ) { 00564 #ifdef DEBUG_MODE 00565 if( debug_mode ) { 00566 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Found reg %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00567 assert( rv < USER_MSG_LENGTH ); 00568 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00569 } 00570 #endif 00571 covered_create_value_change_cb( handle ); 00572 } 00573 } 00574 00575 if( (liter = vpi_iterate( vpiVariables, scope )) != NULL ) { 00576 while( (handle = vpi_scan( liter )) != NULL ) { 00577 type = vpi_get( vpiType, handle ); 00578 #ifdef DEBUG_MODE 00579 if( debug_mode ) { 00580 unsigned int rv; 00581 if( type == vpiReg ) { 00582 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found reg %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00583 } else if( type == vpiIntegerVar ) { 00584 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found integer %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00585 } else if( type == vpiTimeVar ) { 00586 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found time %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00587 } else if( type == vpiRealVar ) { 00588 rv = snprintf( user_msg, USER_MSG_LENGTH, "Found real %s", obf_sig( vpi_get_str( vpiFullName, handle ) ) ); 00589 } 00590 assert( rv < USER_MSG_LENGTH ); 00591 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00592 } 00593 #endif 00594 covered_create_value_change_cb( handle ); 00595 } 00596 } 00597 00598 /* Recursively check scope */ 00599 if( (liter = vpi_iterate( vpiInternalScope, scope )) != NULL ) { 00600 while( (handle = vpi_scan( liter )) != NULL ) { 00601 covered_parse_task_func( handle ); 00602 } 00603 } 00604 00605 } 00606 00607 } 00608 00609 } 00610 00611 } 00612 00613 PROFILE_END; 00614 00615 }
void covered_register | ( | ) |
References covered_sim_calltf().
00855 { 00856 s_vpi_systf_data tf_data; 00857 00858 vpi_printf("VPI: Registering covered_sim system_task"); 00859 00860 tf_data.type = vpiSysTask; 00861 tf_data.tfname = "$covered_sim"; 00862 tf_data.calltf = covered_sim_calltf; 00863 tf_data.compiletf = 0; 00864 tf_data.sizetf = 0; 00865 tf_data.user_data = "$covered_sim"; 00866 00867 vpi_register_systf( &tf_data ); 00868 if (vpi_chk_error(NULL)) { 00869 vpi_printf("Error occured while setting up user %s\n", 00870 "defined system tasks and functions."); 00871 return; 00872 } 00873 00874 }
PLI_INT32 covered_sim_calltf | ( | char * | name | ) |
References add_sym_values_to_sim(), bind_perform(), Catch_anonymous, covered_cb_error_handler(), covered_end_of_sim(), covered_parse_instance(), curr_inst_scope, curr_inst_scope_size, db_read(), debug_mode, FALSE, in_db_name, init_exception_context, malloc_safe_nolimit, out_db_name, PROFILE, PROFILE_END, profiler_set_filename(), profiler_set_mode(), PROFILING_OUTPUT_NAME, READ_MODE_NO_MERGE, sim_initialize(), symtable_create(), sys_task_store_plusarg(), the_exception_context, TRUE, Try, and vcd_symtab_size.
Referenced by covered_register().
00734 { 00735 #endif 00736 PROFILE(COVERED_SIM_CALLTF); 00737 00738 vpiHandle systf_handle, arg_iterator, module_handle; 00739 vpiHandle arg_handle; 00740 s_vpi_vlog_info info; 00741 p_cb_data cb; 00742 int i; 00743 char* argvptr; 00744 sig_link* vsigl; 00745 s_vpi_value value; 00746 00747 /* Initialize the exception handler context structure */ 00748 init_exception_context( the_exception_context ); 00749 00750 systf_handle = vpi_handle( vpiSysTfCall, NULL ); 00751 arg_iterator = vpi_iterate( vpiArgument, systf_handle ); 00752 00753 /* Create callback that will handle the end of simulation */ 00754 cb = (p_cb_data)malloc( sizeof( s_cb_data ) ); 00755 cb->reason = cbEndOfSimulation; 00756 cb->cb_rtn = covered_end_of_sim; 00757 cb->obj = NULL; 00758 cb->time = NULL; 00759 cb->value = NULL; 00760 cb->user_data = NULL; 00761 vpi_register_cb( cb ); 00762 00763 #ifdef TBD 00764 /* Create error handling callback */ 00765 cb = (p_cb_data)malloc( sizeof( s_cb_data ) ); 00766 cb->reason = cbError; 00767 cb->cb_rtn = covered_cb_error_handler; 00768 cb->obj = NULL; 00769 cb->time = NULL; 00770 cb->value = NULL; 00771 cb->user_data = NULL; 00772 vpi_register_cb( cb ); 00773 #endif 00774 00775 /* Get name of CDD database file from system call arguments */ 00776 if( (arg_handle = vpi_scan( arg_iterator )) != NULL ) { 00777 s_vpi_value data; 00778 data.format = vpiStringVal; 00779 vpi_get_value( arg_handle, &data ); 00780 strcpy( in_db_name, data.value.str ); 00781 } 00782 00783 /* Get name of CDD database to write to (default is cov.cdd) and debug mode */ 00784 strcpy( out_db_name, "cov.cdd" ); 00785 profiler_set_mode( FALSE ); 00786 if( vpi_get_vlog_info( &info ) ) { 00787 for( i=1; i<info.argc; i++ ) { 00788 argvptr = info.argv[i]; 00789 if( strncmp( "+covered_cdd=", argvptr, 13 ) == 0 ) { 00790 argvptr += 13; 00791 strcpy( out_db_name, argvptr ); 00792 } else if( strncmp( "+covered_debug", argvptr, 14 ) == 0 ) { 00793 vpi_printf( "covered VPI: Turning debug mode on\n" ); 00794 debug_mode = TRUE; 00795 } else if( strncmp( "+covered_profile=", argvptr, 17 ) == 0 ) { 00796 vpi_printf( "covered VPI: Turning profiler on. Outputting to %s\n", argvptr + 17 ); 00797 profiler_set_mode( TRUE ); 00798 profiler_set_filename( argvptr + 17 ); 00799 } else if( strncmp( "+covered_profile", argvptr, 16 ) == 0 ) { 00800 vpi_printf( "covered VPI: Turning profiler on. Outputting to %s\n", PROFILING_OUTPUT_NAME ); 00801 profiler_set_mode( TRUE ); 00802 profiler_set_filename( PROFILING_OUTPUT_NAME ); 00803 } 00804 sys_task_store_plusarg( info.argv[i] + 1 ); 00805 } 00806 } 00807 00808 /* Read in contents of specified database file */ 00809 Try { 00810 db_read( in_db_name, READ_MODE_NO_MERGE ); 00811 } Catch_anonymous { 00812 vpi_printf( "covered VPI: Unable to read database file\n" ); 00813 vpi_control( vpiFinish, EXIT_FAILURE ); 00814 } 00815 00816 vpi_printf( "covered VPI: Read design information from %s\n", in_db_name ); 00817 00818 /* Bind expressions to signals/functional units */ 00819 Try { 00820 bind_perform( TRUE, 0 ); 00821 } Catch_anonymous { 00822 vpi_control( vpiFinish, EXIT_FAILURE ); 00823 } 00824 00825 /* Add static values to simulator */ 00826 sim_initialize(); 00827 00828 /* Create initial symbol table */ 00829 vcd_symtab = symtable_create(); 00830 00831 /* Initialize the curr_inst_scope structure */ 00832 curr_inst_scope = (char**)malloc( sizeof( char* ) ); 00833 curr_inst_scope[0] = NULL; 00834 curr_inst_scope_size = 1; 00835 00836 /* Parse child instances - associate a signal in the design with a signal in Covered */ 00837 while( (module_handle = vpi_scan( arg_iterator )) != NULL ) { 00838 covered_parse_instance( module_handle ); 00839 } 00840 00841 /* Create timestep symbol table array */ 00842 if( vcd_symtab_size > 0 ) { 00843 timestep_tab = malloc_safe_nolimit( (sizeof( symtable*) * vcd_symtab_size) ); 00844 } 00845 00846 /* Add all of the sym_value structures to the simulation core */ 00847 add_sym_values_to_sim(); 00848 00849 PROFILE_END; 00850 00851 return 0; 00852 00853 }
PLI_INT32 covered_value_change_bin | ( | p_cb_data | cb | ) |
This callback function is called whenever a signal changes within the simulator. It places this value in the Covered symtable and calls the db_do_timestep if this value change occurred on a new timestep.
cb | Pointer to callback data structure from vpi_user.h |
References db_do_timestep(), db_set_symbol_string(), DEBUG, debug_mode, FALSE, last_time, obf_sig, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by covered_create_value_change_cb().
00184 { PROFILE(COVERED_VALUE_CHANGE_BIN); 00185 00186 #ifndef NOIV 00187 s_vpi_value value; 00188 00189 /* Setup value */ 00190 value.format = vpiBinStrVal; 00191 vpi_get_value( cb->obj, &value ); 00192 00193 #ifdef DEBUG_MODE 00194 if( debug_mode ) { 00195 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In covered_value_change_bin, name: %s, time: %" FMT64 "u, value: %s", 00196 obf_sig( vpi_get_str( vpiFullName, cb->obj ) ), (((uint64)cb->time->high << 32) | (uint64)cb->time->low), value.value.str ); 00197 assert( rv < USER_MSG_LENGTH ); 00198 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00199 } 00200 #endif 00201 00202 if( (cb->time->low != (PLI_INT32)(last_time & 0xffffffff)) || (cb->time->high != (PLI_INT32)((last_time >> 32) & 0xffffffff)) ) { 00203 if( !db_do_timestep( last_time, FALSE ) ) { 00204 vpi_control( vpiFinish, EXIT_SUCCESS ); 00205 } 00206 } 00207 last_time = ((uint64)cb->time->high << 32) | (uint64)cb->time->low; 00208 00209 /* Set symbol value */ 00210 db_set_symbol_string( cb->user_data, value.value.str ); 00211 #else 00212 #ifdef DEBUG_MODE 00213 if( debug_mode ) { 00214 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In covered_value_change_bin, name: %s, time: %" FMT64 "u, value: %s", 00215 obf_sig( vpi_get_str( vpiFullName, cb->obj ) ), (((uint64)cb->time->high << 32) | (uint64)cb->time->low), cb->value->value.str ); 00216 assert( rv < USER_MSG_LENGTH ); 00217 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00218 } 00219 #endif 00220 00221 if( (cb->time->low != (PLI_INT32)(last_time & 0xffffffff)) || (cb->time->high != (PLI_INT32)((last_time >> 32) & 0xffffffff)) ) { 00222 if( !db_do_timestep( last_time, FALSE ) ) { 00223 vpi_control( vpiFinish, EXIT_SUCCESS ); 00224 } 00225 } 00226 last_time = ((uint64)cb->time->high << 32) | (uint64)cb->time->low; 00227 00228 /* Set symbol value */ 00229 db_set_symbol_string( cb->user_data, cb->value->value.str ); 00230 #endif 00231 00232 PROFILE_END; 00233 00234 return( 0 ); 00235 00236 }
PLI_INT32 covered_value_change_real | ( | p_cb_data | cb | ) |
This callback function is called whenever a signal changes within the simulator. It places this value in the Covered symtable and calls the db_do_timestep if this value change occurred on a new timestep.
cb | Pointer to callback data structure from vpi_user.h |
References db_do_timestep(), db_set_symbol_string(), DEBUG, debug_mode, FALSE, last_time, obf_sig, print_output(), PROFILE, PROFILE_END, user_msg, and USER_MSG_LENGTH.
Referenced by covered_create_value_change_cb().
00247 { PROFILE(COVERED_VALUE_CHANGE_REAL); 00248 00249 char real_str[64]; 00250 00251 #ifndef NOIV 00252 s_vpi_value value; 00253 00254 /* Setup value */ 00255 value.format = vpiRealVal; 00256 vpi_get_value( cb->obj, &value ); 00257 00258 #ifdef DEBUG_MODE 00259 if( debug_mode ) { 00260 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In covered_value_change_real, name: %s, time: %" FMT64 "u, value: %.16f", 00261 obf_sig( vpi_get_str( vpiFullName, cb->obj ) ), (((uint64)cb->time->high << 32) | (uint64)cb->time->low), value.value.real ); 00262 assert( rv < USER_MSG_LENGTH ); 00263 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00264 } 00265 #endif 00266 00267 if( (cb->time->low != (PLI_INT32)(last_time & 0xffffffff)) || (cb->time->high != (PLI_INT32)((last_time >> 32) & 0xffffffff)) ) { 00268 if( !db_do_timestep( last_time, FALSE ) ) { 00269 vpi_control( vpiFinish, EXIT_SUCCESS ); 00270 } 00271 } 00272 last_time = ((uint64)cb->time->high << 32) | (uint64)cb->time->low; 00273 00274 /* Set symbol value */ 00275 snprintf( real_str, 64, "%.16f", value.value.real ); 00276 db_set_symbol_string( cb->user_data, real_str ); 00277 #else 00278 #ifdef DEBUG_MODE 00279 if( debug_mode ) { 00280 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "In covered_value_change_real, name: %s, time: %" FMT64 "u, value: %.16f", 00281 obf_sig( vpi_get_str( vpiFullName, cb->obj ) ), (((uint64)cb->time->high << 32) | (uint64)cb->time->low), cb->value->value.real ); 00282 assert( rv < USER_MSG_LENGTH ); 00283 print_output( user_msg, DEBUG, __FILE__, __LINE__ ); 00284 } 00285 #endif 00286 00287 if( (cb->time->low != (PLI_INT32)(last_time & 0xffffffff)) || (cb->time->high != (PLI_INT32)((last_time >> 32) & 0xffffffff)) ) { 00288 if( !db_do_timestep( last_time, FALSE ) ) { 00289 vpi_control( vpiFinish, EXIT_SUCCESS ); 00290 } 00291 } 00292 last_time = ((uint64)cb->time->high << 32) | (uint64)cb->time->low; 00293 00294 /* Set symbol value */ 00295 snprintf( real_str, 64, "%.16f", cb->value->value.real ); 00296 db_set_symbol_string( cb->user_data, real_str ); 00297 #endif 00298 00299 PROFILE_END; 00300 00301 return( 0 ); 00302 00303 }
char* gen_next_symbol | ( | ) |
References PROFILE, PROFILE_END, and strdup_safe.
Referenced by covered_create_value_change_cb().
00393 { PROFILE(GEN_NEXT_SYMBOL); 00394 00395 static char symbol[21] = {32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,'\0'}; 00396 static int symbol_index = 19; 00397 int i = 19; 00398 00399 while( (i >= symbol_index) && (symbol[i] == 126) ) { 00400 symbol[i] = 33; 00401 if( (i - 1) < symbol_index ) { 00402 symbol_index--; 00403 if( symbol_index < 0 ) { 00404 return( NULL ); 00405 } 00406 } 00407 i--; 00408 } 00409 symbol[i]++; 00410 00411 PROFILE_END; 00412 00413 return( strdup_safe( symbol + symbol_index ) ); 00414 00415 }
void sym_value_store | ( | char * | sym, | |
char * | value | |||
) |
Stores the given signal symbol and initial value in the sym_value list that will be assigned to the simulator once the timestep table has been allocated.
sym | Symbol string of signal to store | |
value | Initial signal value to store |
References malloc_safe, sym_value_s::next, PROFILE, PROFILE_END, strdup_safe, sym_value_s::sym, and sym_value_s::value.
Referenced by covered_create_value_change_cb().
00125 { PROFILE(SYM_VALUE_STORE); 00126 00127 sym_value* sval; /* Pointer to newly allocated sym_value structure */ 00128 00129 /* Allocate and initialize the sym_value structure */ 00130 sval = (sym_value*)malloc_safe( sizeof( sym_value ) ); 00131 sval->sym = strdup_safe( sym ); 00132 sval->value = strdup_safe( value ); 00133 sval->next = NULL; 00134 00135 /* Add the newly created sym_value structure to the sv list */ 00136 if( sv_head == NULL ) { 00137 sv_head = sv_tail = sval; 00138 } else { 00139 sv_tail->next = sval; 00140 sv_tail = sval; 00141 } 00142 00143 PROFILE_END; 00144 00145 }
void vpi_print_output | ( | const char * | msg | ) |
Displays the given message to standard output.
msg | Message to output to standard output |
Outputs the given message to standard output using the vpi_printf function.
Referenced by print_output().
int block_depth = 0 |
Referenced by db_parallelize_statement().
char* cdd_message = NULL |
User-supplied message to include in the CDD database
Referenced by info_db_write(), info_dealloc(), merge_parse_args(), message_db_read(), report_print_header(), and score_parse_args().
bool cli_debug_mode = FALSE |
char** curr_inst_scope |
Specifies the string Verilog scope that is currently specified in the VCD file.
Referenced by covered_end_of_sim(), covered_parse_instance(), covered_parse_task_func(), covered_sim_calltf(), db_gen_curr_inst_scope(), db_set_vcd_scope(), db_vcd_upscope(), and lxt_parse().
Current size of curr_inst_scope array
Referenced by covered_end_of_sim(), covered_parse_instance(), covered_parse_task_func(), covered_sim_calltf(), db_close(), db_gen_curr_inst_scope(), db_set_vcd_scope(), db_vcd_upscope(), and lxt_parse().
Pointer to the current instance selected by the VCD parser. If this value is NULL, the current instance does not reside in the design specified for coverage.
If set to TRUE, causes debug information to be spewed to screen.
unsigned int flag_global_generation = GENERATION_SV |
Specifies the supported global generation value
Referenced by parser_check_generation(), score_parse_args(), and search_init().
bool flag_output_exclusion_ids = FALSE |
Outputs the exclusion ID for an output coverage point. The exclusion ID can be used by the exclude command for excluding/including coverage points.
Referenced by combination_event(), combination_list_missed(), combination_multi_expr_output(), combination_multi_vars(), combination_two_vars(), combination_unary(), fsm_display_arc_verbose(), line_display_verbose(), memory_display_verbose(), ovl_display_verbose(), report_parse_args(), report_print_header(), and toggle_display_verbose().
int flag_race_check = WARNING |
Specifies how race conditions should be handled
Referenced by race_check_race_count(), race_handle_race_condition(), and score_parse_args().
bool flag_use_command_line_debug = FALSE |
Specifies whether the command-line debugger should be enabled
Referenced by expression_assign(), expression_op_func__idec(), expression_op_func__iinc(), expression_op_func__pdec(), expression_op_func__pinc(), print_output(), score_parse_args(), sim_add_thread(), sim_initialize(), sim_kill_thread(), sim_perform_nba(), sim_simulate(), sim_thread_insert_into_delay_queue(), sim_thread_pop_head(), and sim_thread_push().
bool flag_use_line_width = FALSE |
If set to a boolean value of TRUE, displays combination logic output in a by-line-width format (instead of the user specified Verilog source format).
Referenced by codegen_create_expr(), and report_parse_args().
int* fork_block_depth |
Referenced by db_parallelize_statement().
int fork_depth = -1 |
Referenced by db_parallelize_statement().
int generate_expr_mode = 0 |
Referenced by db_add_function_task_namedblock(), db_add_instance(), and expression_create().
char in_db_name[1024] |
Name of input CDD file
Referenced by covered_sim_calltf().
Informational line for the CDD file.
bool instance_specified = FALSE |
Specifies if -i option was specified
Referenced by db_check_dumpfile_scopes(), parse_design(), and score_parse_args().
uint64 last_time = 0 |
Last simulation time seen from simulator
Referenced by covered_end_of_sim(), covered_value_change_bin(), and covered_value_change_real().
int line_width = DEFAULT_LINE_WIDTH |
Specifies the number of characters wide that an expression will allowed to be output for if the flag_use_line_width value is set to TRUE.
Referenced by codegen_create_expr(), combination_multi_expr_output(), combination_multi_expr_output_length(), report_output_exclusion_reason(), and report_parse_args().
char** merge_in = NULL |
str_link* merge_in_head = NULL |
Pointer to head of list containing names of the input CDD files.
int merge_in_num |
Specifies the number of merged CDD files.
Referenced by info_db_read(), info_db_write(), info_dealloc(), merge_check(), and merged_cdd_db_read().
str_link* merge_in_tail = NULL |
Pointer to tail of list containing names of the input CDD files.
char* merged_file = NULL |
Specifies the output filename of the CDD file that contains the merged data.
Referenced by command_merge(), info_db_write(), merge_check(), and merge_parse_args().
char out_db_name[1024] |
Name of output CDD file
Referenced by covered_end_of_sim(), and covered_sim_calltf().
str_link* race_ignore_mod_head = NULL |
Pointer to head of string list containing the names of modules that should be ignored for race condition checking.
str_link* race_ignore_mod_tail = NULL |
Pointer to tail of string list containing the names of modules that should be ignored for race condition checking.
bool report_covered = FALSE |
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.
Referenced by assertion_funit_verbose(), assertion_instance_verbose(), assertion_report(), combination_funit_verbose(), combination_instance_verbose(), combination_report(), fsm_display_state_verbose(), fsm_display_verbose(), fsm_funit_verbose(), fsm_instance_verbose(), fsm_report(), line_display_verbose(), line_funit_verbose(), line_instance_verbose(), line_report(), memory_funit_verbose(), memory_instance_verbose(), memory_report(), ovl_display_verbose(), report_parse_args(), toggle_funit_verbose(), toggle_instance_verbose(), and toggle_report().
bool report_exclusions = FALSE |
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.
Referenced by assertion_funit_verbose(), assertion_instance_verbose(), combination_funit_verbose(), combination_instance_verbose(), combination_list_missed(), combination_report(), fsm_display_verbose(), fsm_funit_verbose(), fsm_instance_verbose(), fsm_report(), line_funit_verbose(), line_instance_verbose(), line_report(), memory_funit_verbose(), memory_instance_verbose(), memory_report(), report_parse_args(), toggle_funit_verbose(), toggle_instance_verbose(), and toggle_report().
bool report_instance = FALSE |
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.
Referenced by assertion_report(), combination_report(), command_report(), fsm_report(), line_report(), memory_report(), report_generate(), report_parse_args(), report_print_header(), and toggle_report().
struct exception_context the_exception_context[1] |
Exception context structure used by cexcept.h for throwing and catching exceptions.
Referenced by covered_sim_calltf(), and main().
Pointer to the current timestep table array. Please see the file description for how this structure is used.
int timestep_update = 0 |
Specifies timestep increment to display current time
Referenced by db_do_timestep(), and score_parse_args().
char* top_instance = NULL |
Name of top-level instance name
Referenced by command_score(), db_check_dumpfile_scopes(), score_parse_args(), and search_init().
char* top_module = NULL |
Name of top-level module to score
Referenced by command_score(), parse_design(), score_parse_args(), and search_init().
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.
Pointer to the VCD symbol table. Please see the file description for how this structure is used.
int vcd_symtab_size |
Maintains current number of nodes in the VCD symbol table. This value is used to create the appropriately sized timestep_tab array.
void(* vlog_startup_routines[])() |
{ covered_register, 0 }