int VhpiStartupCbHdl::run_callback(void) { gpi_sim_info_t sim_info; sim_info.argc = 0; sim_info.argv = NULL; sim_info.product = gpi_copy_name(vhpi_get_str(vhpiNameP, NULL)); sim_info.version = gpi_copy_name(vhpi_get_str(vhpiToolVersionP, NULL)); gpi_embed_init(&sim_info); free(sim_info.product); free(sim_info.version); return 0; }
VhpiIterator::VhpiIterator(GpiImplInterface *impl, GpiObjHdl *hdl) : GpiIterator(impl, hdl), m_iterator(NULL), m_iter_obj(NULL) { vhpiHandleT iterator; vhpiHandleT vhpi_hdl = m_parent->get_handle<vhpiHandleT>(); vhpiClassKindT type = (vhpiClassKindT)vhpi_get(vhpiKindP, vhpi_hdl); if (NULL == (selected = iterate_over.get_options(type))) { LOG_WARN("VHPI: Implementation does not know how to iterate over %s(%d)", vhpi_get_str(vhpiKindStrP, vhpi_hdl), type); return; } /* Find the first mapping type that yields a valid iterator */ for (one2many = selected->begin(); one2many != selected->end(); one2many++) { iterator = vhpi_iterator(*one2many, vhpi_hdl); if (iterator) break; LOG_DEBUG("vhpi_iterate vhpiOneToManyT=%d returned NULL", *one2many); } if (NULL == iterator) { LOG_DEBUG("vhpi_iterate return NULL for all relationships on %s (%d) kind:%s", vhpi_get_str(vhpiCaseNameP, vhpi_hdl), type, vhpi_get_str(vhpiKindStrP, vhpi_hdl)); selected = NULL; return; } LOG_DEBUG("Created iterator working from scope %d (%s)", vhpi_get(vhpiKindP, vhpi_hdl), vhpi_get_str(vhpiKindStrP, vhpi_hdl)); /* On some simulators (Aldec) vhpiRootInstK is a null level of hierachy * We check that something is going to come back if not we try the level * down */ m_iter_obj = vhpi_hdl; m_iterator = iterator; }
// this function gets handle to signal of specified hierarchical name vhpiHandleT getHandle( char* _szSigName ) { vhpiHandleT hSigHdl,hHdl,hSubItr,hSubHdl; // get handle to root instance if ( ( hHdl = vhpi_handle( vhpiRootInst, NULL ) ) ) { // get handle to signal - try root instance first if ( !( hSigHdl = vhpi_handle_by_name( _szSigName, hHdl ) ) ) { // if failed, iterate internal regions if (( hSubItr = vhpi_iterator( vhpiInternalRegions, hHdl ) )) { while (( hSubHdl = vhpi_scan( hSubItr ) )) if ( !( hSigHdl = vhpi_handle_by_name( _szSigName, hSubHdl ) ) ) { // if failed, print info vhpi_printf( "getHandle(): No signals found searching root and internal regions or ambiguous signal name\n" ); return NULL; } } else { vhpi_printf( "getHandle(): No internal regions found\n" ); return NULL; } } // if getting handle succeeded, print information on console... if ( strcmp( vhpi_get_str( vhpiKindStrP, hSigHdl ), "vhpiPortDeclK" ) == 0 ) // ...with mode in case of port vhpi_printf( "getHandle(): Port %s found: kind %s, mode %s\n",vhpi_get_str( vhpiFullNameP, hSigHdl ), vhpi_get_str( vhpiKindStrP, hSigHdl ), conv_mode( vhpi_get( vhpiModeP, hSigHdl ) ) ); else // ...without mode in case of other object vhpi_printf( "getHandle(): Object %s found: kind %s\n", vhpi_get_str( vhpiFullNameP, hSigHdl ), vhpi_get_str( vhpiKindStrP, hSigHdl ) ); return hSigHdl; } else { vhpi_printf( "getHandle(): No root instance found\n" ); return NULL; } }
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 };
GpiIterator::Status VhpiIterator::next_handle(std::string &name, GpiObjHdl **hdl, void **raw_hdl) { vhpiHandleT obj; GpiObjHdl *new_obj; if (!selected) return GpiIterator::END; /* We want the next object in the current mapping. * If the end of mapping is reached then we want to * try then next one until a new object is found */ do { obj = NULL; if (m_iterator) { obj = vhpi_scan(m_iterator); if (obj && (vhpiProcessStmtK == vhpi_get(vhpiKindP, obj))) { LOG_DEBUG("Skipping %s (%s)", vhpi_get_str(vhpiFullNameP, obj), vhpi_get_str(vhpiKindStrP, obj)); obj=NULL; continue; } if (obj) { LOG_DEBUG("Found an item %s", vhpi_get_str(vhpiFullNameP, obj)); break; } else { LOG_DEBUG("vhpi_scan on %d returned NULL", *one2many); } LOG_DEBUG("End of vhpiOneToManyT=%d iteration", *one2many); m_iterator = NULL; } else { LOG_DEBUG("No valid vhpiOneToManyT=%d iterator", *one2many); } if (++one2many >= selected->end()) { obj = NULL; break; } m_iterator = vhpi_iterator(*one2many, m_iter_obj); } while (!obj); if (NULL == obj) { LOG_DEBUG("No more children, all relationships tested"); return GpiIterator::END; } const char *c_name = vhpi_get_str(vhpiCaseNameP, obj); if (!c_name) { int type = vhpi_get(vhpiKindP, obj); if (type < VHPI_TYPE_MIN) { *raw_hdl = (void*)obj; return GpiIterator::NOT_NATIVE_NO_NAME; } LOG_DEBUG("Unable to get the name for this object of type %d", type); return GpiIterator::NATIVE_NO_NAME; } name = c_name; LOG_DEBUG("vhpi_scan found %s (%d) kind:%s name:%s", name.c_str(), vhpi_get(vhpiKindP, obj), vhpi_get_str(vhpiKindStrP, obj), vhpi_get_str(vhpiCaseNameP, obj)); /* We try and create a handle internally, if this is not possible we return and GPI will try other implementations with the name */ std::string fq_name = m_parent->get_fullname(); if (fq_name == ":") { fq_name += name; } else { fq_name += "." + name; } VhpiImpl *vhpi_impl = reinterpret_cast<VhpiImpl*>(m_impl); new_obj = vhpi_impl->create_gpi_obj_from_handle(obj, name, fq_name); if (new_obj) { *hdl = new_obj; return GpiIterator::NATIVE; } else return GpiIterator::NOT_NATIVE; }
// 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 adds new object to structure TValObjPtrs* addValObj( vhpiHandleT _hNewHandle, TValObjPtrs* _pActualPointer, int _nActualSize ) { TValObjPtrs hNewHandle; hNewHandle.hHdl = _hNewHandle; hNewHandle.vValue = getFieldValue( _hNewHandle ); hNewHandle.nIndex = _nActualSize; hNewHandle.nType = 0; for ( int i = 0; i < 10; i++ ) { hNewHandle.enumOnes[i] = -1; hNewHandle.enumZeros[i] = -1; } hNewHandle.enumMin = 2147483647; hNewHandle.enumMax = 0; hNewHandle.szName = strdup( (char*)vhpi_get_str( vhpiNameP, _hNewHandle ) ); hNewHandle.pBoolVar = new bool; hNewHandle.pIntVar = new int; hNewHandle.pRealVar = new double; hNewHandle.pUserVars = NULL; if ( _hNewHandle ) { if ( ( hNewHandle.vValue->format >= vhpiEnumVecVal ) && ( hNewHandle.vValue->format <= vhpiRealVecVal ) ) { // if array type ports, when numElems is defined hNewHandle.pBoolVecVar = new bool [hNewHandle.vValue->numElems]; hNewHandle.pIntVecVar = new int [hNewHandle.vValue->numElems]; hNewHandle.pRealVecVar = new double [hNewHandle.vValue->numElems]; } else { hNewHandle.pBoolVecVar = new bool; hNewHandle.pIntVecVar = new int; hNewHandle.pRealVecVar = new double; } // detect binary logic enum types to enable numerical conversions if ( ( hNewHandle.vValue->format == vhpiEnumVal ) || ( hNewHandle.vValue->format == vhpiEnumVecVal ) ) { vhpiHandleT hLiteralIt = NULL; vhpiHandleT hLiteralHdl = NULL; vhpiHandleT hTypeHdl = NULL; int nTypeIndex = 0; int nOnesIndex = 0; int nZerosIndex = 0; // get handle to object type hTypeHdl = vhpi_handle( vhpiBaseType, _hNewHandle ); // iterate on all literals of scalar type if (( hLiteralIt = vhpi_iterator( vhpiEnumLiterals, hTypeHdl ) )); // iterate on all literals of array's element type else (( hLiteralIt = vhpi_iterator( vhpiEnumLiterals, vhpi_handle( vhpiElemSubtype, hTypeHdl ) ) )); if ( hLiteralIt ) while (( hLiteralHdl = vhpi_scan( hLiteralIt ) )) { // get literal string value char* szStrVal; szStrVal = strdup( (char*)vhpi_get_str( vhpiStrValP, hLiteralHdl ) ); // get its position (index) in enum type nTypeIndex = vhpi_get( vhpiPositionP, hLiteralHdl ); // set the limits of indexes in enum type if ( nTypeIndex > hNewHandle.enumMax ) hNewHandle.enumMax = nTypeIndex; if ( nTypeIndex < hNewHandle.enumMin ) hNewHandle.enumMin = nTypeIndex; // check if literal string value belongs to binary logic values set if ( ( strcmp( szStrVal, "1" ) == 0 ) || ( strcmp( szStrVal, "H" ) == 0 ) ) // store indexes of literals treated as one in numeric calculations hNewHandle.enumOnes[nOnesIndex++] = nTypeIndex; else if ( ( strcmp( szStrVal, "0" ) == 0 ) || ( strcmp( szStrVal, "L" ) == 0 ) ) // store indexes of literals treated as zero in numeric calculations hNewHandle.enumZeros[nZerosIndex++] = nTypeIndex; free( szStrVal ); } else vhpi_printf( "addVAlObj(): No enum literals found.\n" ); // if type contains one and zero literals if ( ( nZerosIndex != 0 ) && ( nOnesIndex != 0 ) ) hNewHandle.nType = 1; // release handles vhpi_release_handle( hTypeHdl ); vhpi_release_handle( hLiteralHdl ); } } // reallocate array appended with new structure TValObjPtrs* hTempHandle; int index; // allocate memory for copy of actual handles array hTempHandle = new TValObjPtrs [_nActualSize+1]; // copy array contents for ( index = 0; index < _nActualSize; index++ ) { hTempHandle[index] = _pActualPointer[index]; } // append array with new object handle hTempHandle[index++] = hNewHandle; // remove actual array from memory delete [] _pActualPointer ; // allocate memory for new actual array _pActualPointer = new TValObjPtrs [_nActualSize+1]; // copy array contents from temp array for ( index = 0; index < _nActualSize + 1; index++ ) { _pActualPointer[index] = hTempHandle[index]; } // remove temp array delete [] hTempHandle; return _pActualPointer; }
//---------------------------------------------------------------------------- // 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"); } }