// this function registers callback for vhpiCbValueChange reason // arguments: handles to signal and to user data bool isRegisteredCbValueChange( PLI_VOID( *cb_rtn_name ) (const struct vhpiCbDataS *), vhpiHandleT _hSigHdl, PLI_VOID* _hUserData ) { vhpiCbDataT cbData; vhpiHandleT cbData_Hdl; vhpiErrorInfoT errInf; cbData.cb_rtn = cb_rtn_name; cbData.reason = vhpiCbValueChange; cbData.obj = _hSigHdl; cbData.value = getFieldValue( cbData.obj ); cbData.time = NULL; cbData.user_data = _hUserData; // pass user data handle to callback vhpi_register_cb( &cbData, vhpiReturnCb ); if ( ( cbData_Hdl = vhpi_register_cb( &cbData, vhpiReturnCb ) ) ) return true; else { // check error message and print failure info vhpi_printf( "isRegisteredCbValueChange(): Callback on vhpiCbValueChange reason for signal: %s NOT registered \n", vhpi_get_str( vhpiFullNameP, _hSigHdl ) ); if ( vhpi_check_error( &errInf ) ) vhpi_printf( errInf.message ); else vhpi_printf( "isRegisteredCbValueChange(): No vhpi_check_error() message...\n" ); return false; } }
// this function registers callback for vhpiCbAfterDelay reason // arguments: callback routine name, delay in simulation resolution units vhpiHandleT registerCbAfterDelay( PLI_VOID(*cb_rtn_name) (const struct vhpiCbDataS *), vhpiTimeT _tTime, PLI_VOID* _hUserData ) { vhpiCbDataT cbData; vhpiHandleT cbData_Hdl; vhpiErrorInfoT errInf; cbData.reason = vhpiCbAfterDelay; cbData.cb_rtn = cb_rtn_name; cbData.obj = NULL; cbData.time = &_tTime; cbData.value = NULL; cbData.user_data = _hUserData; if ( ( cbData_Hdl = vhpi_register_cb( &cbData, vhpiReturnCb ) ) ) return cbData_Hdl; else { // check error message and print failure info vhpi_printf( "isRegisteredCbAfterDelay(): Callback on vhpiCbAfterDelay reason NOT registered \n" ); if ( vhpi_check_error( &errInf ) ) vhpi_printf( errInf.message ); else vhpi_printf( "isRegisteredCbAfterDelay(): No vhpi_check_error() message...\n" ); return NULL; } }
// this function registers callback for vhpiCbEndOfSimulation reason // arguments: callback routine name bool isRegisteredCbEndOfSimulation( PLI_VOID(*cb_rtn_name) (const struct vhpiCbDataS *), PLI_VOID* _hUserData ) { vhpiCbDataT cbData; vhpiHandleT cbData_Hdl; vhpiErrorInfoT errInf; cbData.reason = vhpiCbEndOfSimulation ; cbData.cb_rtn = cb_rtn_name; cbData.obj = NULL; cbData.time = NULL; cbData.value = NULL; cbData.user_data = _hUserData; if ( ( cbData_Hdl = vhpi_register_cb( &cbData, vhpiReturnCb ) ) ) return true; else { // check error message and print failure info vhpi_printf( "isRegisteredCbEndOfSimulation(): Callback on vhpiCbEndOfSimulation reason NOT registered \n" ); if ( vhpi_check_error( &errInf ) ) vhpi_printf( errInf.message ); else vhpi_printf( "isRegisteredCbEndOfSimulation(): No vhpi_check_error() message...\n" ); return false; } }
static void startup() { vhpi_printf("hello, world!"); vhpiCbDataT cb_data1 = { .reason = vhpiCbStartOfSimulation, .cb_rtn = start_of_sim, .user_data = (char *)"some user data", }; handle_sos = vhpi_register_cb(&cb_data1, vhpiReturnCb); check_error(); fail_unless(vhpi_get(vhpiStateP, handle_sos) == vhpiEnable); vhpiCbDataT cb_data2 = { .reason = vhpiCbEndOfSimulation, .cb_rtn = end_of_sim }; vhpi_register_cb(&cb_data2, 0); check_error(); vhpi_printf("tool is %s", vhpi_get_str(vhpiNameP, NULL)); vhpiHandleT root = vhpi_handle(vhpiRootInst, NULL); check_error(); fail_if(root == NULL); vhpi_printf("root handle %p", root); handle_x = vhpi_handle_by_name("x", root); check_error(); fail_if(handle_x == NULL); vhpi_printf("x handle %p", handle_x); handle_y = vhpi_handle_by_name("y", root); check_error(); fail_if(handle_y == NULL); vhpi_printf("y handle %p", handle_y); vhpi_release_handle(root); } void (*vhpi_startup_routines[])() = { startup, NULL };
static void start_of_sim(const vhpiCbDataT *cb_data) { vhpi_printf("start of sim callback! user data is '%s'", (char *)cb_data->user_data); long cycles; vhpiTimeT now; vhpi_get_time(&now, &cycles); fail_unless(now.low == 0); fail_unless(now.high == 0); fail_unless(cycles == 0); vhpiValueT value = { .format = vhpiObjTypeVal }; vhpi_get_value(handle_x, &value); check_error(); fail_unless(value.format == vhpiIntVal); fail_unless(value.value.intg == 0); value.value.intg = 5; vhpi_put_value(handle_x, &value, vhpiForcePropagate); check_error(); vhpiTimeT time_5ns = { .low = 5000000 }; vhpiCbDataT cb_data2 = { .reason = vhpiCbAfterDelay, .cb_rtn = after_5ns, .time = &time_5ns }; vhpi_register_cb(&cb_data2, 0); check_error(); } static void end_of_sim(const vhpiCbDataT *cb_data) { vhpi_printf("end of sim callback"); vhpiValueT value = { .format = vhpiObjTypeVal }; vhpi_get_value(handle_y, &value); check_error(); fail_unless(value.format == vhpiIntVal); fail_unless(value.value.intg == 75); vhpi_release_handle(handle_x); vhpi_release_handle(handle_y); vhpi_release_handle(handle_sos); }
static void startup() { vhpi_printf("hello, world!"); vhpiCbDataT cb_data1 = { .reason = vhpiCbStartOfSimulation, .cb_rtn = start_of_sim, .user_data = NULL, }; (void)vhpi_register_cb(&cb_data1, vhpiReturnCb); check_error(); }
int VhpiCbHdl::arm_callback(void) { int ret = 0; vhpiStateT cbState; if (m_state == GPI_PRIMED) return 0; /* Do we already have a handle, if so and it is disabled then just re-enable it */ if (get_handle<vhpiHandleT>()) { cbState = (vhpiStateT)vhpi_get(vhpiStateP, get_handle<vhpiHandleT>()); if (vhpiDisable == cbState) { if (vhpi_enable_cb(get_handle<vhpiHandleT>())) { check_vhpi_error(); goto error; } } } else { vhpiHandleT new_hdl = vhpi_register_cb(&cb_data, vhpiReturnCb); if (!new_hdl) { check_vhpi_error(); LOG_ERROR("VHPI: Unable to register callback a handle for VHPI type %s(%d)", m_impl->reason_to_string(cb_data.reason), cb_data.reason); goto error; } cbState = (vhpiStateT)vhpi_get(vhpiStateP, new_hdl); if (vhpiEnable != cbState) { LOG_ERROR("VHPI ERROR: Registered callback isn't enabled! Got %d\n", cbState); goto error; } m_obj_hdl = new_hdl; } m_state = GPI_PRIMED; return ret; error: m_state = GPI_FREE; return -1; }
static inline int __gpi_register_cb(p_vhpi_cb_user_data user, vhpiCbDataT *cb_data) { /* If the user data already has a callback handle then deregister * before getting the new one */ vhpiHandleT new_hdl = vhpi_register_cb(cb_data, vhpiReturnCb); int ret = 0; if (!new_hdl) { LOG_CRITICAL("VHPI: Unable to register callback a handle for VHPI type %s(%d)", vhpi_reason_to_string(cb_data->reason), cb_data->reason); check_vhpi_error(); ret = -1; } if (user->cb_hdl != NULL) { printf("VHPI: Attempt to register a callback that's already registered...\n"); gpi_deregister_callback(&user->gpi_hdl); } user->cb_hdl = new_hdl; return ret; }
static void test_bin_str(void) { vhpiHandleT root = vhpi_handle(vhpiRootInst, NULL); check_error(); vhpiHandleT hb = vhpi_handle_by_name("b", root); check_error(); vhpiHandleT hv = vhpi_handle_by_name("v", root); check_error(); char b_str[2] = { 0xff, 0xff }; vhpiValueT b_value = { .format = vhpiBinStrVal, .bufSize = sizeof(b_str), .value.str = (vhpiCharT *)b_str }; vhpi_get_value(hb, &b_value); check_error(); vhpi_printf("b bit string '%s' %x", b_str); fail_unless(strcmp(b_str, "0") == 0); vhpiValueT v_value = { .format = vhpiBinStrVal, .bufSize = 0, .value.str = NULL }; const int need = vhpi_get_value(hv, &v_value); check_error(); vhpi_printf("need %d bytes for v string", need); v_value.value.str = malloc(need); v_value.bufSize = need; fail_if(v_value.value.str == NULL); fail_unless(vhpi_get_value(hv, &v_value) == 0); check_error(); vhpi_printf("v bit string '%s'", v_value.value.str); fail_unless(strcmp((char *)v_value.value.str, "0011") == 0); free(v_value.value.str); vhpi_release_handle(root); vhpi_release_handle(hb); vhpi_release_handle(hv); } static void y_value_change(const vhpiCbDataT *cb_data) { vhpiValueT value = { .format = vhpiObjTypeVal }; vhpi_get_value(handle_y, &value); check_error(); fail_unless(value.format == vhpiIntVal); vhpi_printf("y value changed to %d", value.value.intg); if (value.value.intg == 75) { test_bin_str(); vhpi_control(vhpiFinish); check_error(); } else { value.value.intg++; vhpi_put_value(handle_x, &value, vhpiForcePropagate); check_error(); } } static void after_5ns(const vhpiCbDataT *cb_data) { vhpi_printf("after_5ns callback!"); long cycles; vhpiTimeT now; vhpi_get_time(&now, &cycles); fail_unless(now.low == 5000000); fail_unless(now.high == 0); fail_unless(cycles == 0); vhpiValueT value = { .format = vhpiObjTypeVal }; vhpi_get_value(handle_y, &value); check_error(); fail_unless(value.format == vhpiIntVal); fail_unless(value.value.intg == 6); value.value.intg = 70; vhpi_put_value(handle_x, &value, vhpiForcePropagate); check_error(); vhpiCbDataT cb_data2 = { .reason = vhpiCbValueChange, .cb_rtn = y_value_change, .obj = handle_y }; vhpi_register_cb(&cb_data2, 0); check_error(); }
PLI_VOID oscil_c_vhpi_proc(const struct vhpiCbDataS *cb_data_p) { vhpiCbDataT cbDataAction; vhpiHandleT SigHdl; vhpiHandleT CallbackHdl; vhpiValueT value; vhpiTimeT time; vhpiValueT *initValue; vhpi_printf( "Registering signals CLK & CLR for event changes\n"); vhpi_printf( "invec_data.clear = %d\n", invec_data.clear); vhpi_printf( "invec_data.clock = %d\n", invec_data.clock); //Entity: oscil_c_vhpi //port CLK : in STD_LOGIC; //port CLR : in STD_LOGIC; //port F0 : out STD_LOGIC; //port F1 : out STD_LOGIC; value.format = vhpiCharVal; //signals are BIT cbDataAction.value = &value; cbDataAction.reason = vhpiCbValueChange; //on signal value change event cbDataAction.time = &time; cbDataAction.cb_rtn = SignalChangedEvent; //get signal by name if ( (SigHdl = vhpi_handle_by_name(":UUT:U1:CLK",0) ) ) { cbDataAction.obj = SigHdl; //connect callback to the signal //register if ( (CallbackHdl = vhpi_register_cb(&cbDataAction, vhpiReturnCb) ) ) { vhpi_printf("callback on signal %s registered \n",vhpi_get_str(vhpiNameP,SigHdl)); registration = 1; } else { vhpi_printf("callback on signal %s NOT registered \n",vhpi_get_str(vhpiNameP,SigHdl)); registration = 0; } } //get signal by name if ( (SigHdl = vhpi_handle_by_name(":UUT:U1:CLR",0) ) ) { cbDataAction.obj = SigHdl; //connect callback to the signal //register if ( (CallbackHdl = vhpi_register_cb(&cbDataAction, vhpiReturnCb) ) ) { vhpi_printf("callback on signal %s registered \n",vhpi_get_str(vhpiNameP,SigHdl)); registration = 1; } else { vhpi_printf("callback on signal %s NOT registered \n",vhpi_get_str(vhpiNameP,SigHdl)); registration = 0; } } if(registration) { vhpi_printf("**********************************************************************\n"); vhpi_printf("* Active-HDL - SystemC/VHDL/Verilog/EDIF/C/C++ interface initialized *\n"); vhpi_printf("* -----------------------VHPI VERSION------------------------------- *\n"); vhpi_printf("**********************************************************************\n"); invec_data.clock = 0; invec_data.clear = 0; invec_data.clock_prev = invec_data.clock; invec_data.clear_prev = invec_data.clear; Q = 0; initValue = (vhpiValueT*) malloc(sizeof(vhpiValueT)); initValue->format = vhpiEnumVal; initValue->value.enumv = 2; //Initialize out port F0 if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F0",0) ) ) { if(vhpi_put_value(SigHdl,initValue,vhpiForcePropagate)) vhpi_printf("E R R O R : Cannot update F0 port\n"); } else vhpi_printf("E R R O R : Cannot get handler for F0 port\n"); //Initialize out port F1 if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F1",0) ) ) { if(vhpi_put_value(SigHdl,initValue,vhpiForcePropagate)) vhpi_printf("E R R O R : Cannot update F1 port\n"); } else vhpi_printf("E R R O R : Cannot get handler for F1 port\n"); } else { vhpi_printf("**************************************************************************\n"); vhpi_printf("* Active-HDL - SystemC/VHDL/Verilog/EDIF/C/C++ interface not initialized *\n"); vhpi_printf("* -----------------------VHPI VERSION----------------------------------- *\n"); vhpi_printf("**************************************************************************\n"); } }