Add basic support for vpi_get64() to return the nexus pointer
This commit is contained in:
parent
49fc24a798
commit
ebf2dc1685
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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); }
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue