static void start_of_sim(const vhpiCbDataT *cb_data) { vhpi_printf("start_of_sim"); fail_unless(phys_to_i64(vhpiFS) == 1ll); fail_unless(phys_to_i64(vhpiPS) == 1000ll); fail_unless(phys_to_i64(vhpiNS) == 1000000ll); fail_unless(phys_to_i64(vhpiUS) == 1000000000ll); fail_unless(phys_to_i64(vhpiMS) == 1000000000000ll); fail_unless(phys_to_i64(vhpiS) == 1000000000000000ll); fail_unless(phys_to_i64(vhpiMN) == 1000000000000000ll * 60); fail_unless(phys_to_i64(vhpiHR) == 1000000000000000ll * 60 * 60); vhpiPhysT res_limit = vhpi_get_phys(vhpiResolutionLimitP, NULL); check_error(); fail_unless(phys_to_i64(res_limit) == phys_to_i64(vhpiFS)); vhpiHandleT root = vhpi_handle(vhpiRootInst, NULL); check_error(); fail_if(root == NULL); vhpiHandleT handle_x = vhpi_handle_by_name("x", root); check_error(); fail_if(handle_x == NULL); vhpi_printf("x handle %p", handle_x); vhpiPhysT x_val = vhpi_get_phys(vhpiPhysValP, handle_x); check_error(); fail_unless(phys_to_i64(x_val) == 2); vhpiHandleT handle_weight_type = vhpi_handle(vhpiType, handle_x); check_error(); fail_if(handle_weight_type == NULL); vhpiHandleT handle_weight_cons = vhpi_handle_by_index(vhpiConstraints, handle_weight_type, 0); check_error(); fail_if(handle_weight_cons == NULL); vhpiPhysT weight_left = vhpi_get_phys(vhpiPhysLeftBoundP, handle_weight_cons); check_error(); fail_unless(phys_to_i64(weight_left) == -100); vhpiPhysT weight_right = vhpi_get_phys(vhpiPhysRightBoundP, handle_weight_cons); check_error(); fail_unless(phys_to_i64(weight_right) == 4000); vhpi_release_handle(handle_weight_cons); vhpi_release_handle(handle_weight_type); vhpi_release_handle(handle_x); vhpi_release_handle(root); }
/** * @name Find the root handle * @brief Find the root handle using a optional name * * Get a handle to the root simulator object. This is usually the toplevel. * * FIXME: In VHPI we always return the first root instance * * TODO: Investigate possibility of iterating and checking names as per VHPI * If no name is defined, we return the first root instance. * * If name is provided, we check the name against the available objects until * we find a match. If no match is found we return NULL */ gpi_sim_hdl gpi_get_root_handle(const char* name) { FENTER vhpiHandleT root; vhpiHandleT dut; gpi_sim_hdl rv; root = vhpi_handle(vhpiRootInst, NULL); check_vhpi_error(); if (!root) { LOG_ERROR("VHPI: Attempting to get the root handle failed"); FEXIT 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 };
// 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; } }
// 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; }
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(); }