1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2009-2009 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#include "svdpi.h"
#include <cstdio>
//======================================================================
// clang-format off
#if defined(VERILATOR)
# ifdef T_DPI_CONTEXT_NOOPT
# include "Vt_dpi_context_noopt__Dpi.h"
# else
# include "Vt_dpi_context__Dpi.h"
# endif
#elif defined(VCS)
# include "../vc_hdrs.h"
#elif defined(CADENCE)
# define NEED_EXTERNS
#else
# error "Unknown simulator for DPI test"
#endif
#ifdef VERILATOR
# include "verilated.h"
#endif
// clang-format on
#ifdef NEED_EXTERNS
extern "C" {
extern int dpic_line();
extern int dpic_save(int value);
extern int dpic_restore();
extern unsigned dpic_getcontext();
extern unsigned dpic_get1();
}
#endif
//======================================================================
int dpic_line() {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
}
#ifdef VERILATOR
static int didDump = 0;
if (didDump++ == 0) Verilated::scopesDump();
#endif
const char* scopenamep = svGetNameFromScope(scope);
if (!scopenamep) {
printf("%%Warning: svGetNameFromScope failed\n");
return 0;
}
if (scope != svGetScopeFromName(scopenamep)) {
printf("%%Warning: svGetScopeFromName repeat failed\n");
return 0;
}
const char* filenamep = "";
int lineno = 0;
if (svGetCallerInfo(&filenamep, &lineno)) {
printf("Call from %s:%d:%s\n", filenamep, lineno, scopenamep);
} else {
printf("%%Warning: svGetCallerInfo failed\n");
return 0;
}
(void)svGetCallerInfo(nullptr, nullptr); // Check doesn't segflt
return lineno;
}
extern int Dpic_Unique;
int Dpic_Unique = 0; // Address used for uniqueness
extern int Dpic_Value;
int Dpic_Value = 0; // Address used for testing
int dpic_save(int value) {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
}
// Use union to avoid cast to different size pointer warnings
union valpack {
void* ptr;
int i;
} vp;
// Load the value here, and below, to test we can reinsert correctly
if (svPutUserData(scope, &Dpic_Unique, &Dpic_Value)) {
printf("%%Warning: svPutUserData failed (initial)\n");
return 0;
}
if (void* userp = svGetUserData(scope, &Dpic_Unique)) {
if (userp != &Dpic_Value) {
printf("%%Warning: svGetUserData failed (initial wrong data)\n");
return 0;
}
} else {
printf("%%Warning: svGetUserData failed (initial)\n");
return 0;
}
vp.i = value;
(void)vp.i;
if (svPutUserData(scope, &Dpic_Unique, vp.ptr)) {
printf("%%Warning: svPutUserData failed\n");
return 0;
}
return 1;
}
int dpic_restore() {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
}
if (void* userp = svGetUserData(scope, (void*)&Dpic_Unique)) {
// Use union to avoid cast to different size pointer warnings
union valpack {
void* ptr;
int i;
} vp;
vp.ptr = userp;
return vp.i;
} else {
printf("%%Warning: svGetUserData failed\n");
return 0;
}
}
unsigned dpic_getcontext() {
svScope scope = svGetScope();
printf("%%Info: svGetScope returned scope (%p) with name %s\n", //
scope, svGetNameFromScope(scope));
return (unsigned)(uintptr_t)scope;
}
unsigned dpic_get1() { return 1; }
void dpic_final() {
static int s_once = 0;
if (s_once++) return;
printf("%s:\n", __func__);
#ifdef VERILATOR
// Cover VerilatedImp::userDump
Verilated::internalsDump();
#endif
}
|