Add basic support for vpi_get64() to return the nexus pointer

This commit is contained in:
Cary R 2026-01-25 17:48:22 -08:00
parent 49fc24a798
commit ebf2dc1685
12 changed files with 93 additions and 45 deletions

View File

@ -442,7 +442,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
char *escname;
const char *ident;
fstHandle new_ident;
int nexus_id;
int64_t nexus_id;
unsigned size;
PLI_INT32 item_type;
@ -557,7 +557,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
} else escname = strdup(name);
/* Some signals can have an alias so handle that. */
nexus_id = vpi_get(_vpiNexusId, item);
nexus_id = vpi_get64(_vpiNexusId, item);
ident = 0;
if (nexus_id) ident = find_nexus_ident(nexus_id);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2002-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -523,7 +523,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
const char* name;
const char* ident;
int nexus_id;
int64_t nexus_id;
switch (vpi_get(vpiType, item)) {
@ -558,7 +558,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
nexus_id = vpi_get(_vpiNexusId, item);
nexus_id = vpi_get64(_vpiNexusId, item);
if (nexus_id) {
ident = find_nexus_ident(nexus_id);
} else {

View File

@ -582,7 +582,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
const char* name;
const char* ident;
int nexus_id;
int64_t nexus_id;
switch (vpi_get(vpiType, item)) {
@ -617,7 +617,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
if (skip || vpi_get(vpiAutomatic, item)) break;
name = vpi_get_str(vpiName, item);
nexus_id = vpi_get(_vpiNexusId, item);
nexus_id = vpi_get64(_vpiNexusId, item);
if (nexus_id) {
ident = find_nexus_ident(nexus_id);
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -510,7 +510,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
const char *fullname;
const char *prefix;
const char *ident;
int nexus_id;
int64_t nexus_id;
unsigned size;
PLI_INT32 item_type;
@ -622,7 +622,7 @@ static void scan_item(unsigned depth, vpiHandle item, int skip)
prefix = is_escaped_id(name) ? "\\" : "";
/* Some signals can have an alias so handle that. */
nexus_id = vpi_get(_vpiNexusId, item);
nexus_id = vpi_get64(_vpiNexusId, item);
ident = 0;
if (nexus_id) ident = find_nexus_ident(nexus_id);

View File

@ -1,7 +1,7 @@
#ifndef IVL_vcd_priv_H
#define IVL_vcd_priv_H
/*
* Copyright (c) 2003-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2003-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -52,8 +52,8 @@ EXTERN void vcd_names_delete(struct vcd_names_list_s*tab);
/*
* Keep a map of nexus ident's to help with alias detection.
*/
EXTERN const char*find_nexus_ident(int nex);
EXTERN void set_nexus_ident(int nex, const char *id);
EXTERN const char*find_nexus_ident(int64_t nex);
EXTERN void set_nexus_ident(int64_t nex, const char *id);
EXTERN void nexus_ident_delete(void);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2011 Stephen Williams (steve@icarus.com)
* Copyright (c) 2010-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -44,18 +44,18 @@
The _vpiNexusId is a private (int) property of IVL simulators.
*/
static std::map<int,const char*> nexus_ident_map;
static std::map<int64_t,const char*> nexus_ident_map;
extern "C" const char*find_nexus_ident(int nex)
extern "C" const char*find_nexus_ident(int64_t nex)
{
std::map<int,const char*>::const_iterator cur = nexus_ident_map.find(nex);
std::map<int64_t,const char*>::const_iterator cur = nexus_ident_map.find(nex);
if (cur == nexus_ident_map.end())
return 0;
else
return cur->second;
}
extern "C" void set_nexus_ident(int nex, const char*id)
extern "C" void set_nexus_ident(int64_t nex, const char*id)
{
nexus_ident_map[nex] = id;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2025 Martin Whitaker (icarus@martin-whitaker.me.uk)
* Copyright (c) 2019-2026 Martin Whitaker (icarus@martin-whitaker.me.uk)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -57,6 +57,7 @@ vpiHandle vpi_scan(vpiHandle) { return 0; }
// for processing properties
PLI_INT32 vpi_get(int, vpiHandle) { return 0; }
PLI_INT64 vpi_get64(int, vpiHandle) { return 0; }
char* vpi_get_str(PLI_INT32, vpiHandle) { return 0; }
// delay processing
@ -202,6 +203,7 @@ vpip_routines_s vpi_routines = {
.iterate = vpi_iterate,
.scan = vpi_scan,
.get = vpi_get,
.get64 = vpi_get64,
.get_str = vpi_get_str,
.get_delays = vpi_get_delays,
.put_delays = vpi_put_delays,

View File

@ -1,7 +1,7 @@
#ifndef VPI_USER_H
#define VPI_USER_H
/*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -543,6 +543,7 @@ extern vpiHandle vpi_handle_multi(PLI_INT32 type, vpiHandle ref1, vpiHandle ref
extern void vpi_get_time(vpiHandle obj, s_vpi_time*t);
extern PLI_INT32 vpi_get(int property, vpiHandle ref);
extern PLI_INT64 vpi_get64(int property, vpiHandle ref);
extern char *vpi_get_str(PLI_INT32 property, vpiHandle ref);
extern void vpi_get_value(vpiHandle expr, p_vpi_value value);
@ -709,6 +710,7 @@ typedef struct {
vpiHandle (*iterate)(PLI_INT32, vpiHandle);
vpiHandle (*scan)(vpiHandle);
PLI_INT32 (*get)(int, vpiHandle);
PLI_INT64 (*get64)(int, vpiHandle);
char* (*get_str)(PLI_INT32, vpiHandle);
void (*get_delays)(vpiHandle, p_vpi_delay);
void (*put_delays)(vpiHandle, p_vpi_delay);

View File

@ -21,7 +21,7 @@ invalidPointerCast:class_type.cc:332
invalidPointerCast:class_type.cc:338
invalidPointerCast:class_type.cc:339
cstyleCast:ufunc.cc:80
cstyleCast:vpi_priv.cc:226
cstyleCast:vpi_priv.cc:229
cstyleCast:vpi_scope.cc:615
// Skip the sscanf() field width limit warning
@ -29,12 +29,12 @@ invalidscanf:compile.cc:597
invalidscanf:compile.cc:609
// By convention we put statics at the top scope.
variableScope:vpi_priv.cc:623
variableScope:vpi_priv.cc:647
// Changing this breaks the compile
constParameterPointer:vthread.cc:423
useInitializationList:delay.cc:513
constParameterPointer:vpi_priv.cc:1434
constParameterPointer:vpi_priv.cc:1458
// Operator new/delete are static so cannot override
duplInheritedMember:vvp_net.h:1476
@ -79,27 +79,27 @@ duplicateValueTernary:class_type.cc:268
// cppcheck is wrong this can be true or false
knownConditionTrueFalse:vthread.cc:2986
knownConditionTrueFalse:vpi_priv.cc:657
knownConditionTrueFalse:vpi_priv.cc:1955
knownConditionTrueFalse:vpi_priv.cc:681
knownConditionTrueFalse:vpi_priv.cc:1979
// cppcheck is wrong this is already const
constParameterPointer:vpi_tasks.cc:259
// For some cases this expression can be different
duplicateExpression:vpi_signal.cc:1189
duplicateExpression:vpi_signal.cc:1207
// cppcheck does not relize this is deleted[] in the called routine
leakNoVarFunctionCall:compile.cc:452
// Yes, these are not currently initialized in the constructor
// All are added after __vpiSysTaskCall is built
uninitMemberVar:vpi_priv.h:944
uninitMemberVar:vpi_priv.h:946
// All are added after __vpiSignal is built
uninitMemberVar:vpi_priv.h:392
uninitMemberVar:vpi_priv.h:394
// run_run_ptr is added after the event is built
uninitMemberVar:delay.h:79
// The array values are added after it is allocated
noConstructor:vpi_priv.h:778
noConstructor:vpi_priv.h:780
// The enum values are added after this is built
uninitMemberVar:enum_type.cc:54
// The names for the enum values are added after allocation
@ -107,10 +107,10 @@ uninitMemberVar:enum_type.cc:100
// The thread values get assigned after being created
uninitMemberVar:vthread.cc:316
// The mod path has the values added after creation
uninitMemberVar:delay.cc:1005
uninitMemberVar:delay.cc:1045
uninitMemberVar:delay.cc:1006
uninitMemberVar:delay.cc:1046
// The intermod path has the values added after creation
uninitMemberVar:delay.cc:1395
uninitMemberVar:delay.cc:1396
// The island values are set after creation
uninitDerivedMemberVar:island_tran.cc:60
// The cb_data is set after creation
@ -124,24 +124,24 @@ uninitMemberVar:vpi_scope.cc:353
// The real var values are set after creation
uninitMemberVar:vpi_real.cc:158
// The PV values are set after creation
uninitMemberVar:vpi_signal.cc:1577
uninitMemberVar:vpi_signal.cc:1595
// The info/is_user_defn are added ater creation
uninitMemberVar:vpi_tasks.cc:41
// All the values are set after creation using the default constructor
noConstructor:vpi_tasks.cc:158
// We check memory usage using valgrind.
unsafeClassCanLeak:vpi_priv.h:750
unsafeClassCanLeak:vpi_priv.h:752
unsafeClassCanLeak:permaheap.h:47
// Index calculation
thisSubtraction:vpi_priv.h:430
thisSubtraction:vpi_priv.h:432
thisSubtraction:array_common.h:91
// The interface is from the standard.
constParameterCallback:vpi_priv.cc:1110
constParameterCallback:vpi_priv.cc:1134
constParameterPointer:vpi_priv.cc:1134
constParameterPointer:vpi_mcd.cc:158
constParameterPointer:vpi_priv.cc:1110
// cppcheck is missing the code adds a \0 at the previous location.
knownConditionTrueFalse:vpi_modules.cc:118
@ -220,13 +220,13 @@ unusedFunction:lib_main.cc:76
// alias_word()
unusedFunction:array.cc:848
// intermodpath_delete()
unusedFunction:delay.cc:1462
unusedFunction:delay.cc:1463
// count_force4_pool()
unusedFunction:schedule.cc:404
// call_scope()
unusedFunction:ufunc.h:62
// get_bit()
unusedFunction:vpi_priv.h:477
unusedFunction:vpi_priv.h:479
// copy_bits()
unusedFunction:vvp_net.cc:615
// mov()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2008-2026 Stephen Williams (steve@icarus.com)
* Copyright (c) 2023 Leo Moser (leo.moser@pm.me)
*
* This source code is free software; you can redistribute it
@ -67,6 +67,9 @@ __vpiHandle::~__vpiHandle()
int __vpiHandle::vpi_get(int)
{ return vpiUndefined; }
int64_t __vpiHandle::vpi_get64(int code)
{ return (code == _vpiNexusId) ? 0 : vpiUndefined; }
char* __vpiHandle::vpi_get_str(int)
{ return 0; }
@ -331,6 +334,8 @@ static const char* vpi_property_str(PLI_INT32 code)
return "vpiTimePrecision";
case vpiSize:
return "vpiSize";
case _vpiNexusId:
return "_vpiNexusId";
default:
snprintf(buf, sizeof(buf), "%d", (int)code);
}
@ -449,6 +454,25 @@ PLI_INT32 vpi_get(int property, vpiHandle ref)
return res;
}
PLI_INT64 vpi_get64(int property, vpiHandle ref)
{
// For now we only support getting the nexus id.
if ((ref == 0) || (property != _vpiNexusId)) {
fprintf(vpi_trace, "vpi_get64(%s, %p) is not currently supported.\n",
vpi_property_str(property), ref);
return vpiUndefined;
}
int64_t res = ref->vpi_get64(property);
if (vpi_trace) {
fprintf(vpi_trace, "vpi_get64(%s, %p) --> %" PRId64 "\n",
vpi_property_str(property), ref, res);
}
return res;
}
char* vpi_get_str(PLI_INT32 property, vpiHandle ref)
{
/* We don't care what the ref is there is only one delay selection. */

View File

@ -124,6 +124,7 @@ class __vpiHandle {
virtual int get_type_code(void) const =0;
virtual int vpi_get(int code);
virtual int64_t vpi_get64(int code);
virtual char* vpi_get_str(int code);
virtual void vpi_get_value(p_vpi_value val);
@ -352,6 +353,7 @@ extern void vpip_make_root_iterator(class __vpiHandle**&table,
*/
struct __vpiSignal : public __vpiHandle {
int vpi_get(int code) override;
int64_t vpi_get64(int code) override;
char* vpi_get_str(int code) override;
void vpi_get_value(p_vpi_value val) override;
vpiHandle vpi_put_value(p_vpi_value val, int flags) override;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2001-2026 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -593,15 +593,30 @@ static int signal_get(int code, vpiHandle ref)
return _vpiNoThr;
#endif
default:
fprintf(stderr, "VPI error: unknown signal_get property %d.\n",
code);
return vpiUndefined;
}
}
/*
* implement vpi_get64 for vpiReg objects.
*/
static int64_t signal_get64(int code, vpiHandle ref)
{
struct __vpiSignal*rfp = dynamic_cast<__vpiSignal*>(ref);
assert(rfp);
switch (code) {
// This private property must return zero when undefined.
case _vpiNexusId:
if (rfp->msb.get_value() == rfp->lsb.get_value())
return (int) (uintptr_t) rfp->node;
else
return 0;
return reinterpret_cast<int64_t>(rfp->node);
return 0;
default:
fprintf(stderr, "VPI error: unknown signal_get property %d.\n",
fprintf(stderr, "VPI error: unknown signal_get64 property %d.\n",
code);
return vpiUndefined;
}
@ -1050,6 +1065,9 @@ vvp_vector4_t vec4_from_vpi_value(s_vpi_value*vp, unsigned wid)
int __vpiSignal::vpi_get(int code)
{ return signal_get(code, this); }
int64_t __vpiSignal::vpi_get64(int code)
{ return signal_get64(code, this); }
char* __vpiSignal::vpi_get_str(int code)
{ return signal_get_str(code, this); }