// Value related functions int VhpiSignalObjHdl::set_signal_value(int value) { switch (m_value.format) { case vhpiEnumVal: case vhpiLogicVal: { m_value.value.enumv = value ? vhpi1 : vhpi0; break; } case vhpiEnumVecVal: case vhpiLogicVecVal: { unsigned int i; for (i=0; i<m_size; i++) m_value.value.enumvs[m_size-i-1] = value&(1<<i) ? vhpi1 : vhpi0; break; } default: { LOG_CRITICAL("VHPI type of object has changed at runtime: ABORTING"); } } vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiForcePropagate); check_vhpi_error(); return 0; }
// Value related functions int VhpiLogicSignalObjHdl::set_signal_value(long value) { switch (m_value.format) { case vhpiEnumVal: case vhpiLogicVal: { m_value.value.enumv = value ? vhpi1 : vhpi0; break; } case vhpiEnumVecVal: case vhpiLogicVecVal: { int i; for (i=0; i<m_num_elems; i++) m_value.value.enumvs[m_num_elems-i-1] = value&(1<<i) ? vhpi1 : vhpi0; m_value.numElems = m_num_elems; break; } default: { LOG_ERROR("VHPI: Unable to set a std_logic signal with a raw value"); return -1; } } if (vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiDepositPropagate)) { check_vhpi_error(); return -1; } return 0; }
int VhpiLogicSignalObjHdl::set_signal_value(std::string &value) { switch (m_value.format) { case vhpiEnumVal: case vhpiLogicVal: { m_value.value.enumv = chr2vhpi(value.c_str()[0]); break; } case vhpiEnumVecVal: case vhpiLogicVecVal: { int len = value.length(); // Since we may not get the numElems correctly from the sim and have to infer it // we also need to set it here as well each time. m_value.numElems = len; if (len > m_num_elems) { LOG_DEBUG("VHPI: Attempt to write string longer than (%s) signal %d > %d", m_name.c_str(), len, m_num_elems); m_value.numElems = m_num_elems; } std::string::iterator iter; int i = 0; for (iter = value.begin(); (iter != value.end()) && (i < m_num_elems); iter++, i++) { m_value.value.enumvs[i] = chr2vhpi(*iter); } // Fill bits at the end of the value to 0's for (i = len; i < m_num_elems; i++) { m_value.value.enumvs[i] = vhpi0; } break; } default: { LOG_ERROR("VHPI: Unable to set a std_logic signal with a raw value"); return -1; } } if (vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiDepositPropagate)) { check_vhpi_error(); return -1; } return 0; }
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); }
int VhpiSignalObjHdl::set_signal_value(std::string &value) { switch (m_value.format) { case vhpiEnumVal: case vhpiLogicVal: { m_value.value.enumv = chr2vhpi(value.c_str()[0]); break; } case vhpiEnumVecVal: case vhpiLogicVecVal: { unsigned int len = value.length(); if (len > m_size) { LOG_ERROR("VHPI: Attempt to write string longer than signal %d > %d", len, m_size); return -1; } std::string::iterator iter; unsigned int i = 0; for (iter = value.begin(); iter != value.end(); iter++, i++) { m_value.value.enumvs[i] = chr2vhpi(*iter); } // Fill bits at the end of the value to 0's for (i = len; i < m_size; i++) { m_value.value.enumvs[i] = vhpi0; } break; } default: { LOG_CRITICAL("VHPI type of object has changed at runtime: ABORTING"); } } vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiForcePropagate); check_vhpi_error(); return 0; }
// Value related functions int VhpiSignalObjHdl::set_signal_value(long value) { switch (m_value.format) { case vhpiEnumVecVal: case vhpiLogicVecVal: { int i; for (i=0; i<m_num_elems; i++) m_value.value.enumvs[m_num_elems-i-1] = value&(1<<i); // Since we may not get the numElems correctly from the sim and have to infer it // we also need to set it here as well each time. m_value.numElems = m_num_elems; break; } case vhpiLogicVal: case vhpiEnumVal: { m_value.value.enumv = value; break; } case vhpiIntVal: { m_value.value.intg = value; break; } case vhpiCharVal: { m_value.value.ch = value; break; } default: { LOG_ERROR("VHPI: Unable to handle this format type %s", ((VhpiImpl*)GpiObjHdl::m_impl)->format_to_string(m_value.format)); return -1; } } if (vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiDepositPropagate)) { check_vhpi_error(); return -1; } return 0; }
int VhpiSignalObjHdl::set_signal_value(double value) { switch (m_value.format) { case vhpiRealVal: m_value.numElems = 1; m_value.bufSize = sizeof(value); m_value.value.real = value; break; default: { LOG_ERROR("VHPI: Unable to set a Real handle this format type %s", ((VhpiImpl*)GpiObjHdl::m_impl)->format_to_string(m_value.format)); return -1; } } if (vhpi_put_value(GpiObjHdl::get_handle<vhpiHandleT>(), &m_value, vhpiDepositPropagate)) { check_vhpi_error(); return -1; } return 0; }
// this function updates object's value of index in in information table bool objUpdateMain( int i , TValObjPtrs* _pValObjs, void* _pVar, int _bVarType) { if ( ( (_pValObjs[i].vValue)->format == vhpiEnumVal ) && ( ( _bVarType == typeIntVar ) || ( ( _pValObjs[i].nType == 0 ) && ( _bVarType == typeDefaultVar ) ) ) ) { // if scalar enum object and int variable (default for scalar objects of non-logic enum type) if (( _pVar )) // if user variable specified, copies it to port structure *(_pValObjs[i].pIntVar) = *(int*)_pVar; // updates value structure with variable value (_pValObjs[i].vValue)->value.enumv = *(_pValObjs[i].pIntVar); if ( ( *(_pValObjs[i].pIntVar) > _pValObjs[i].enumMax ) || ( *(_pValObjs[i].pIntVar) < _pValObjs[i].enumMin ) ) vhpi_printf( "objUpdate(): Variable value %d exceeds %s type's range.\n", *(_pValObjs[i].pIntVar), _pValObjs[i].szName ); } else if ( ( (_pValObjs[i].vValue)->format == vhpiEnumVal ) && ( ( _bVarType == typeBoolVar ) || ( ( _pValObjs[i].nType == 1 ) && ( _bVarType == typeDefaultVar ) ) ) ) { // if scalar enum object and bool variable (default for scalar objects of logic enum type) if (( _pVar )) // if user variable specified, copies it to port structure *(_pValObjs[i].pBoolVar) = *(bool*)_pVar; // updates value structure with variable value if ( _pValObjs[i].nType == 0 ) // if non-logic enum type (_pValObjs[i].vValue)->value.enumv = *(_pValObjs[i].pBoolVar) ? 1 : 0; if ( _pValObjs[i].nType == 1 ) // if logic enum type (_pValObjs[i].vValue)->value.enumv = *(_pValObjs[i].pBoolVar) ? _pValObjs[i].enumOnes[0] : _pValObjs[i].enumZeros[0]; } else if ( ( (_pValObjs[i].vValue)->format == vhpiEnumVecVal ) && ( ( _bVarType == typeIntVecVar ) || ( ( _pValObjs[i].nType == 0 ) && ( _bVarType == typeDefaultVar ) ) ) ) { // if vector of enum object and int[n] variable (default for vector objects of non-logic enum type) if (( _pVar )) // if user variable specified, copies it to port structure memcpy( _pValObjs[i].pIntVecVar, _pVar, _pValObjs[i].vValue->bufSize ); // updates value structure with variable value for ( int j = 0; j < _pValObjs[i].vValue->numElems; j++ ) { // check if integer value fits the object type range if ( ( _pValObjs[i].pIntVecVar[j] <= _pValObjs[i].enumMax ) && ( _pValObjs[i].pIntVecVar[j] >= _pValObjs[i].enumMin ) ) (_pValObjs[i].vValue)->value.enumvs[j] = _pValObjs[i].pIntVecVar[j]; else { // if integer value exceeds the object type range vhpi_printf( "objUpdate(): Variable value %d exceeds %s type range. Object value set to the leftmost value in type\n", _pValObjs[i].pIntVecVar[j], _pValObjs[i].szName ); (_pValObjs[i].vValue)->value.enumvs[j] = _pValObjs[i].enumMin; } } } else if ( ( (_pValObjs[i].vValue)->format == vhpiEnumVecVal ) && ( _bVarType == typeBoolVecVar ) ) { // if vector of enum object and bool[n] variable if (( _pVar )) // if user variable specified, copies it to port structure memcpy( _pValObjs[i].pBoolVecVar, _pVar, _pValObjs[i].vValue->bufSize ); // updates value structure with variable value if ( _pValObjs[i].nType == 0 ) // if non-logic type for ( int j = 0; j < _pValObjs[i].vValue->numElems; j++ ) (_pValObjs[i].vValue)->value.enumvs[j] = _pValObjs[i].pBoolVecVar[j] ? _pValObjs[i].enumMin + 1 : _pValObjs[i].enumMin; if ( _pValObjs[i].nType == 1 ) // if logic type for ( int j = 0; j < _pValObjs[i].vValue->numElems; j++ ) (_pValObjs[i].vValue)->value.enumvs[j] = _pValObjs[i].pBoolVecVar[j] ? _pValObjs[i].enumOnes[0] : _pValObjs[i].enumZeros[0]; } else if ( ( (_pValObjs[i].vValue)->format == vhpiEnumVecVal ) && ( _pValObjs[i].nType == 1 ) && ( ( _bVarType == typeIntVar ) || ( _bVarType == typeDefaultVar ) ) ) { // if vector of enum object and int variable (default for vector objects of logic enum type) if (( _pVar )) // if user variable specified, copies it to port structure memcpy( _pValObjs[i].pIntVar, _pVar, _pValObjs[i].vValue->bufSize ); // updates value structure with variable value int2logicv( _pValObjs[i] ); } else if ( ( (_pValObjs[i].vValue)->format == vhpiIntVal ) && ( ( _bVarType == typeIntVar ) || ( _bVarType == typeDefaultVar ) ) ) { // if integer port and int variable (default for integer ports) if (( _pVar )) // if user variable specified, copies it to port structure *(_pValObjs[i].pIntVar) = *(int*)_pVar; // updates value structure with variable value (_pValObjs[i].vValue)->value.intg = *(_pValObjs[i].pIntVar); } else if ( ( (_pValObjs[i].vValue)->format == vhpiIntVecVal ) && ( ( _bVarType == typeIntVecVar ) || ( _bVarType == typeDefaultVar ) ) ) { // if array of integer port and int[n] variable (default for array of integer port) if (( _pVar )) // if user variable specified, copies it to port structure memcpy( _pValObjs[i].pIntVecVar, _pVar, _pValObjs[i].vValue->bufSize ); // updates value structure with variable value for ( int j = 0; j < _pValObjs[i].vValue->numElems; j++ ) (_pValObjs[i].vValue)->value.intgs[j] = _pValObjs[i].pIntVecVar[j]; } else if ( ( (_pValObjs[i].vValue)->format == vhpiRealVal ) && ( ( _bVarType == typeRealVar ) || ( _bVarType == typeDefaultVar ) ) ) { // if real port and double variable (default for real port) if (( _pVar )) // if user variable specified, copies it to port structure *(_pValObjs[i].pRealVar) = *(double*)_pVar; // updates value structure with variable value (_pValObjs[i].vValue)->value.real = *(_pValObjs[i].pRealVar); } else if ( ( (_pValObjs[i].vValue)->format == vhpiRealVecVal ) && ( ( _bVarType == typeRealVecVar ) || ( _bVarType == typeDefaultVar ) ) ) { // if array of real port and double[n] variable (default for array of real port) if (( _pVar )) // if user variable specified, copies it to port structure memcpy( _pValObjs[i].pRealVecVar, _pVar, _pValObjs[i].vValue->bufSize ); // updates value structure with variable value for ( int j = 0; j < _pValObjs[i].vValue->numElems; j++ ) (_pValObjs[i].vValue)->value.reals[j] = _pValObjs[i].pRealVecVar[j]; } else { vhpi_printf( "objUpdate(): Object %s type is not supported\n", _pValObjs[i].szName ); return false; } vhpiErrorInfoT errInf; if ( ( vhpi_put_value( _pValObjs[i].hHdl, _pValObjs[i].vValue, vhpiDepositPropagate ) ) == 0 ) { // vhpi_printf("Signal value update succeeded\n"); return true; } else { vhpi_printf( "objUpdate(): Object %s value update failed\n", _pValObjs[i].szName ); // check error info from vhpi_put_value() if ( vhpi_check_error( &errInf ) ) vhpi_printf( "objUpdate(): vhpi_check_error() message: \n", errInf.message ); else vhpi_printf( "objUpdate(): No vhpi_check_error() message...\n" ); return false; } }
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(); }
//---------------------------------------------------------------------------- // Callback for signal value changing event //---------------------------------------------------------------------------- PLI_VOID SignalChangedEvent (const struct vhpiCbDataS * cbDatap) { int signalValue = 0; vhpiHandleT SigHdl; vhpiValueT *value; value = (vhpiValueT*) malloc(sizeof(vhpiValueT)); value->format = vhpiEnumVal; if (cbDatap->obj){ // display information about current signal vhpi_printf("E V E N T : signal %s has value %c at time : %u\n", vhpi_get_str(vhpiNameP,cbDatap->obj), cbDatap->value->value.ch, cbDatap->time->low); if(cbDatap->value->value.ch == '1') signalValue = 0; else signalValue = 1; if(!strcmp(vhpi_get_str(vhpiNameP,cbDatap->obj),"CLK")) { invec_data.clock = signalValue; vhpi_printf("invec_data.clock = %d\n", signalValue); } else { signalValue = !signalValue; vhpi_printf("invec_data.clear = %d\n", signalValue); invec_data.clear = signalValue; } //------------------------------------------------------------------------- if ((invec_data.clock_prev == 0 && invec_data.clock == 1) || (invec_data.clock_prev == 1 && invec_data.clock == 0)) { vhpi_printf("***********************************\n"); vhpi_printf("Simulation time : %u\n",cbDatap->time->low); vhpi_printf("Module : OSCIL : Read inputs\n"); vhpi_printf("Port CLK=%d Port CLR=%d\n", invec_data.clock, invec_data.clear); vhpi_printf("Current Q %d\n", Q); //CLK'event and CLK = '1' if (invec_data.clock_prev == 0 && invec_data.clock == 1) { vhpi_printf("CLK - Rising edge occured _|¯\n"); if (!invec_data.clear) Q = Q + 1; } else //CLK'event and CLK = '0' if (invec_data.clock_prev == 1 && invec_data.clock == 0) { vhpi_printf("CLK - Falling edge occured ¯|_\n"); if (!invec_data.clear) Q = Q + 1; } vhpi_printf("Current Q %d\n", Q); switch (Q) { case 3 : outvec_data.f0 = 1; value->value.enumv = 3; if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F0",0) ) ) { if(vhpi_put_value(SigHdl,value,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"); break; case 4 : outvec_data.f0 = 0; value->value.enumv = 2; if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F0",0) ) ) { if(vhpi_put_value(SigHdl,value,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"); break; case 7 : outvec_data.f1 = 1; value->value.enumv = 3; if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F1",0) ) ) { if(vhpi_put_value(SigHdl,value,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"); break; case 8 : outvec_data.f1 = 0; value->value.enumv = 2; if( (SigHdl = vhpi_handle_by_name(":UUT:U1:F1",0) ) ) { if(vhpi_put_value(SigHdl,value,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"); Q = 0; break; default : break; } invec_data.clock_prev = invec_data.clock; invec_data.clear_prev = invec_data.clear; vhpi_printf("Module : OSCIL : Update outputs\n"); vhpi_printf("Port F0=%d Port F1=%d\n", outvec_data.f0, outvec_data.f1); vhpi_printf("***********************************\n"); } //------------------------------------------------------------------- } }
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"); } }