Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods.

This commit is contained in:
Wilson Snyder 2024-03-02 09:02:21 -05:00
parent 91dd3c5fac
commit fa7234ff68
14 changed files with 196 additions and 17 deletions

View File

@ -14,11 +14,10 @@ Verilator 5.023 devel
**Major:**
* Support 1800-2023 keywords.
* Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods.
**Minor:**
* Add warning on 'TOP'-named modules (#4935). [Yanglin Xun]
* Fix invalid cast on string structure creation (#4921). [esynr3z]

View File

@ -770,6 +770,36 @@ int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
return true;
}
//======================================================================
// Time
int svGetTime(const svScope scope, svTimeVal* time) {
if (VL_UNLIKELY(!time)) return -1;
const QData qtime = VL_TIME_Q();
VlWide<2> itime;
VL_SET_WQ(itime, qtime);
time->low = itime[0];
time->high = itime[1];
return 0;
}
int svGetTimeUnit(const svScope scope, int32_t* time_unit) {
if (VL_UNLIKELY(!time_unit)) return -1;
const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
if (!vscopep) { // Null asks for global, not unlikely
*time_unit = Verilated::threadContextp()->timeunit();
} else {
*time_unit = vscopep->timeunit();
}
return 0;
}
int svGetTimePrecision(const svScope scope, int32_t* time_precision) {
if (VL_UNLIKELY(!time_precision)) return -1;
*time_precision = Verilated::threadContextp()->timeprecision();
return 0;
}
//======================================================================
// Disables

View File

@ -150,10 +150,21 @@ extern "C" {
#define vpiIntegerNet 681
#define vpiLogicNet vpiNet
#define vpiTimeNet 682
#define vpiUnionNet 525
#define vpiShortRealNet 526
#define vpiRealNet 527
#define vpiByteNet 528
#define vpiShortIntNet 529
#define vpiIntNet 530
#define vpiLongIntNet 531
#define vpiBitNet 532
#define vpiInterconnectNet 533
#define vpiInterconnectArray 534
#define vpiStructNet 683
#define vpiBreak 684
#define vpiContinue 685
#define vpiPackedArrayNet 693
#define vpiNettypeDecl 523
#define vpiConstraintExpr 747
#define vpiElseConst 748
#define vpiImplication 749
@ -174,6 +185,8 @@ extern "C" {
#define vpiBaseTypespec 703
#define vpiElemTypespec 704
#define vpiNetTypedefAlias 705
#define vpiInputSkew 706
#define vpiOutputSkew 707
#define vpiGlobalClocking 708
@ -206,7 +219,8 @@ extern "C" {
#define vpiMessages 735
#define vpiLoopVars 737
#define vpiConcurrentAssertions 740
#define vpiConcurrentAssertion 740
#define vpiConcurrentAssertions vpiConcurrentAssertion
#define vpiMatchItem 741
#define vpiMember 742
#define vpiElement 743
@ -221,6 +235,7 @@ extern "C" {
/**************************************************************************/
/************************ generic object properties ***********************/
/**************************************************************************/
#define vpiTop 600
#define vpiUnit 602
@ -255,7 +270,6 @@ extern "C" {
#define vpiModportPort 2
/* vpiPort is also a port type. It is defined in vpi_user.h */
#define vpiConstantVariable 612
#define vpiStructUnionMember 615
@ -407,6 +421,7 @@ extern "C" {
/***************************** structure *****************************/
/**************************** CALLBACK REASONS ****************************/
#define vpiMethodFuncCall 648
#define cbStartOfThread 600 /* callback on thread creation */
#define cbEndOfThread 601 /* callback on thread termination */
#define cbEnterThread 602 /* callback on reentering thread */

View File

@ -7,7 +7,7 @@
* This file contains the constant definitions, structure definitions,
* and routine declarations used by SystemVerilog DPI.
*
* This file is from the SystemVerilog IEEE 1800-2017 Annex I.
* This file is from the SystemVerilog IEEE 1800-2023 Annex I.
*/
#ifndef INCLUDED_SVDPI
@ -111,6 +111,26 @@ typedef uint32_t svBitVecVal;
((N) == 32 ? (VALUE) : \
(((VALUE) & (1 << (N))) ? ((VALUE) | ~SV_MASK(N)) : ((VALUE) & SV_MASK(N))))
#ifndef VPI_TIME
#define VPI_TIME
typedef struct t_vpi_time {
int32_t type;
uint32_t high, low;
double real;
} s_vpi_time, *p_vpi_time;
#define vpiScaledRealTime 1
#define vpiSimTime 2
#define vpiSuppressTime 3
#endif
/* time value */
typedef s_vpi_time svTimeVal;
/* time value types */
#define sv_scaled_real_time vpiScaledRealTime
#define sv_sim_time vpiSimTime
/*
* Implementation-dependent representation.
*/
@ -277,7 +297,7 @@ XXTERN svScope svGetScope( void );
/*
* Set context for subsequent export function execution.
* This function must be called before calling an export function, unless
* This function shall be called before calling an export function, unless
* the export function is called while executing an import function. In that
* case the export function shall inherit the scope of the surrounding import
* function. This is known as the "default scope".
@ -297,7 +317,7 @@ XXTERN svScope svGetScopeFromName(const char* scopeName);
/*
* Store an arbitrary user data pointer for later retrieval by svGetUserData()
* The userKey is generated by the user. It must be guaranteed by the user to
* The userKey is generated by the user. It needs to be guaranteed by the user to
* be unique from all other userKey's for all unique data storage requirements
* It is recommended that the address of static functions or variables in the
* user's C code be used as the userKey.
@ -329,24 +349,49 @@ XXTERN void* svGetUserData(const svScope scope, void* userKey);
* modified. Whether this information is available or not is implementation-
* specific. Note that the string provided (if any) is owned by the SV
* implementation and is valid only until the next call to any SV function.
* Applications must not modify this string or free it
* Applications shall not modify this string or free it.
*/
XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber);
/*
* Returns 1 if the current execution thread is in the disabled state.
* Disable protocol must be adhered to if in the disabled state.
* Disable protocol shall be adhered to if in the disabled state.
*/
XXTERN int svIsDisabledState( void );
/*
* Imported functions call this API function during disable processing to
* acknowledge that they are correctly participating in the DPI disable protocol.
* This function must be called before returning from an imported function that is
* This function shall be called before returning from an imported function that is
* in the disabled state.
*/
XXTERN void svAckDisabledState( void );
/* Mantis 5713/D9
* Retrieve the current simulation time, scaled to the time unit of the scope.
* If scope is NULL, then time is scaled to the simulation time unit.
* It is an error to call svGetTime() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTime(const svScope scope, svTimeVal* time);
/*
* Retrieve the time unit for scope.
* If scope is NULL, then simulation time unit is retrieved.
* It is an error to call svGetTimeUnit() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTimeUnit(const svScope scope, int32_t* time_unit);
/*
* Retrieve the time precision for scope.
* If scope is NULL, then simulation time unit is retrieved.
* It is an error to call svGetTimePrecision() with an invalid svScope.
* This function returns -1 for all error cases, 0 upon success.
*/
XXTERN int svGetTimePrecision(const svScope scope, int32_t* time_precision);
/*
**********************************************************
* DEPRECATED PORTION OF FILE STARTS FROM HERE.

View File

@ -1,7 +1,7 @@
/*******************************************************************************
* vpi_user.h
*
* IEEE Std 1800-2017 Programming Language Interface (PLI)
* IEEE Std 1800-2023 Programming Language Interface (PLI)
*
* This file contains the constant definitions, structure definitions, and
* routine declarations used by the SystemVerilog Verification Procedural
@ -344,6 +344,9 @@ typedef PLI_UINT32 *vpiHandle;
#define vpiSupply0 11 /* supply-0 net */
#define vpiNone 12 /* no default net type (1364-2001) */
#define vpiUwire 13 /* unresolved wire net (1364-2005) */
#define vpiNettypeNet 14 /* user-defined nettype net */
#define vpiNettypeNetSelect 15 /* user-defined nettype net subelement */
#define vpiInterconnect 16 /* interconnect net */
#define vpiExplicitScalared 23 /* explicitly scalared (Boolean) */
#define vpiExplicitVectored 24 /* explicitly vectored (Boolean) */
@ -573,6 +576,9 @@ typedef PLI_UINT32 *vpiHandle;
/******************************* time structure *******************************/
#ifndef VPI_TIME /* added in 1800-2023 */
#define VPI_TIME
typedef struct t_vpi_time
{
PLI_INT32 type; /* [vpiScaledRealTime, vpiSimTime,
@ -587,6 +593,8 @@ typedef struct t_vpi_time
#define vpiSimTime 2
#define vpiSuppressTime 3
#endif
/****************************** delay structures ******************************/
typedef struct t_vpi_delay
@ -741,9 +749,8 @@ typedef struct t_vpi_arrayvalue
typedef struct t_vpi_systf_data
{
PLI_INT32 type; /* vpiSysTask, vpiSysFunc */
PLI_INT32 sysfunctype; /* vpiSysTask, vpi[Int,Real,Time,Sized,
SizedSigned]Func */
PLI_BYTE8 *tfname; /* first character must be '$' */
PLI_INT32 sysfunctype; /* vpi[Int,Real,Time,Sized,SizedSigned]Func */
PLI_BYTE8 *tfname; /* first character has to be '$' */
PLI_INT32 (*calltf)(PLI_BYTE8 *);
PLI_INT32 (*compiletf)(PLI_BYTE8 *);
PLI_INT32 (*sizetf)(PLI_BYTE8 *); /* for sized function callbacks only */

View File

@ -10,8 +10,12 @@ Time scale of t is 100s / 10ms
acc%0t=1234567890123456789000000000000.000000ns acc%0d=12345678901234567890
[1000000000000000.000000ns] stime%0t=1000000000000000.000000ns stime%0d=10000 stime%0f=10000.000000
[1000000000000000.000000ns] rtime%0t=1000000000000000.000000ns rtime%0d=10000 rtime%0f=10000.000000
global svGetTime = 0 0,100000000
global svGetTimeUnit = 0 -2 svGetTmePrecision = 0 -2
global vpiSimTime = 0,100000000 vpiScaledRealTime = 1e+08
global vpiTimeUnit = -2 vpiTimePrecision = -2
top.t svGetTime = 0 0,100000000
top.t svGetTimeUnit = 0 2 svGetTmePrecision = 0 -2
top.t vpiSimTime = 0,100000000 vpiScaledRealTime = 10000
top.t vpiTimeUnit = 2 vpiTimePrecision = -2
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 10ms / 10ns
acc%0t=123456789012345678900000000.000000ns acc%0d=12345678901234567890
[600000000.000000ns] stime%0t=600000000.000000ns stime%0d=60 stime%0f=60.000000
[600000000.000000ns] rtime%0t=600000000.000000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,60000000
global svGetTimeUnit = 0 -2 svGetTmePrecision = 0 -8
global vpiSimTime = 0,60000000 vpiScaledRealTime = 6e+07
global vpiTimeUnit = -2 vpiTimePrecision = -8
top.t svGetTime = 0 0,60000000
top.t svGetTimeUnit = 0 -2 svGetTmePrecision = 0 -8
top.t vpiSimTime = 0,60000000 vpiScaledRealTime = 60
top.t vpiTimeUnit = -2 vpiTimePrecision = -8
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1fs / 1fs
acc%0t=12345678901234.567890ns acc%0d=12345678901234567890
[0.000060ns] stime%0t=0.000060ns stime%0d=60 stime%0f=60.000000
[0.000060ns] rtime%0t=0.000060ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,60
global svGetTimeUnit = 0 -15 svGetTmePrecision = 0 -15
global vpiSimTime = 0,60 vpiScaledRealTime = 60
global vpiTimeUnit = -15 vpiTimePrecision = -15
top.t svGetTime = 0 0,60
top.t svGetTimeUnit = 0 -15 svGetTmePrecision = 0 -15
top.t vpiSimTime = 0,60 vpiScaledRealTime = 60
top.t vpiTimeUnit = -15 vpiTimePrecision = -15
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1ms / 10ns
acc%0t=12345678901234567890000000.000000ns acc%0d=12345678901234567890
[60000000.000000ns] stime%0t=60000000.000000ns stime%0d=60 stime%0f=60.000000
[60000000.000000ns] rtime%0t=60000000.000000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,6000000
global svGetTimeUnit = 0 -3 svGetTmePrecision = 0 -8
global vpiSimTime = 0,6000000 vpiScaledRealTime = 6e+06
global vpiTimeUnit = -3 vpiTimePrecision = -8
top.t svGetTime = 0 0,6000000
top.t svGetTimeUnit = 0 -3 svGetTmePrecision = 0 -8
top.t vpiSimTime = 0,6000000 vpiScaledRealTime = 60
top.t vpiTimeUnit = -3 vpiTimePrecision = -8
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1ns / 1ns
acc%0t=12345678901234567890.000000ns acc%0d=12345678901234567890
[60.000000ns] stime%0t=60.000000ns stime%0d=60 stime%0f=60.000000
[60.000000ns] rtime%0t=60.000000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,60
global svGetTimeUnit = 0 -9 svGetTmePrecision = 0 -9
global vpiSimTime = 0,60 vpiScaledRealTime = 60
global vpiTimeUnit = -9 vpiTimePrecision = -9
top.t svGetTime = 0 0,60
top.t svGetTimeUnit = 0 -9 svGetTmePrecision = 0 -9
top.t vpiSimTime = 0,60 vpiScaledRealTime = 60
top.t vpiTimeUnit = -9 vpiTimePrecision = -9
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1ps / 1fs
acc%0t=12345678901234567.890000ns acc%0d=12345678901234567890
[0.060000ns] stime%0t=0.060000ns stime%0d=60 stime%0f=60.000000
[0.060000ns] rtime%0t=0.060000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,60000
global svGetTimeUnit = 0 -12 svGetTmePrecision = 0 -15
global vpiSimTime = 0,60000 vpiScaledRealTime = 60000
global vpiTimeUnit = -12 vpiTimePrecision = -15
top.t svGetTime = 0 0,60000
top.t svGetTimeUnit = 0 -12 svGetTmePrecision = 0 -15
top.t vpiSimTime = 0,60000 vpiScaledRealTime = 60
top.t vpiTimeUnit = -12 vpiTimePrecision = -15
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1s / 10ns
acc%0t=12345678901234567890000000000.000000ns acc%0d=12345678901234567890
[60000000000.000000ns] stime%0t=60000000000.000000ns stime%0d=60 stime%0f=60.000000
[60000000000.000000ns] rtime%0t=60000000000.000000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 1,1705032704
global svGetTimeUnit = 0 0 svGetTmePrecision = 0 -8
global vpiSimTime = 1,1705032704 vpiScaledRealTime = 6e+09
global vpiTimeUnit = 0 vpiTimePrecision = -8
top.t svGetTime = 0 1,1705032704
top.t svGetTimeUnit = 0 0 svGetTmePrecision = 0 -8
top.t vpiSimTime = 1,1705032704 vpiScaledRealTime = 60
top.t vpiTimeUnit = 0 vpiTimePrecision = -8
*-* All Finished *-*

View File

@ -10,8 +10,12 @@ Time scale of t is 1us / 1ns
acc%0t=12345678901234567890000.000000ns acc%0d=12345678901234567890
[60000.000000ns] stime%0t=60000.000000ns stime%0d=60 stime%0f=60.000000
[60000.000000ns] rtime%0t=60000.000000ns rtime%0d=60 rtime%0f=60.000000
global svGetTime = 0 0,60000
global svGetTimeUnit = 0 -6 svGetTmePrecision = 0 -9
global vpiSimTime = 0,60000 vpiScaledRealTime = 60000
global vpiTimeUnit = -6 vpiTimePrecision = -9
top.t svGetTime = 0 0,60000
top.t svGetTimeUnit = 0 -6 svGetTmePrecision = 0 -9
top.t vpiSimTime = 0,60000 vpiScaledRealTime = 60
top.t vpiTimeUnit = -6 vpiTimePrecision = -9
*-* All Finished *-*

View File

@ -13,10 +13,14 @@
#include "vpi_user.h"
#include <cstdio>
#include <iostream>
// These require the above. Comment prevents clang-format moving them
#include "TestCheck.h"
#include "TestVpi.h"
int errors = 0;
//======================================================================
#define NEED_EXTERNS
@ -29,7 +33,45 @@ extern void dpii_check();
//======================================================================
void show(vpiHandle obj) {
void dpi_bad() {
{
int res = svGetTime(0, nullptr);
TEST_CHECK_EQ(res, -1);
}
{
int res = svGetTimeUnit(0, nullptr);
TEST_CHECK_EQ(res, -1);
}
{
int res = svGetTimePrecision(0, nullptr);
TEST_CHECK_EQ(res, -1);
}
}
void dpi_show(svScope obj) {
const char* namep;
if (obj) {
namep = svGetNameFromScope(obj);
} else {
namep = "global";
}
svTimeVal t; // aka s_vpi_time
t.type = vpiSimTime;
int gres = svGetTime(obj, &t);
vpi_printf(const_cast<char*>("%s svGetTime = %d %d,%d\n"), namep, gres, (int)t.high,
(int)t.low);
// These will both print the precision, because the 0 asks for global scope
int32_t u = 99;
int ures = svGetTimeUnit(obj, &u);
int32_t p = 99;
int pres = svGetTimePrecision(obj, &p);
vpi_printf(const_cast<char*>("%s svGetTimeUnit = %d %d"), namep, ures, u);
vpi_printf(const_cast<char*>(" svGetTmePrecision = %d %d\n"), pres, p);
}
void vpi_show(vpiHandle obj) {
const char* namep;
if (obj) {
namep = vpi_get_str(vpiName, obj);
@ -55,12 +97,21 @@ void show(vpiHandle obj) {
}
void dpii_check() {
show(0);
dpi_bad();
dpi_show(0);
vpi_show(0);
svScope smod = svGetScopeFromName("top.t");
if (!smod) {
vpi_printf(const_cast<char*>("-- Cannot svGetScopeFromName\n"));
} else {
dpi_show(smod);
}
TestVpiHandle mod = vpi_handle_by_name((PLI_BYTE8*)"top.t", NULL);
if (!mod) {
vpi_printf(const_cast<char*>("-- Cannot vpi_find module\n"));
} else {
show(mod);
vpi_show(mod);
}
}