CIRCT 23.0.0git
Loading...
Searching...
No Matches
SvDpiRuntime.cpp
Go to the documentation of this file.
1//===- SvDpiRuntime.cpp - Runtime-loaded svdpi entry points ----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Provide the small svDpi* subset needed by DpiEntryPoints.cpp, but resolve
10// the underlying simulator implementation at runtime instead of linking a
11// fixed MtiPli import library.
12//
13//===----------------------------------------------------------------------===//
14
15// On MSVC++ we need svdpi.h to declare exports, not imports.
16#define DPI_PROTOTYPES
17#undef XXTERN
18#define XXTERN DPI_EXTERN DPI_DLLESPEC
19#undef EETERN
20#define EETERN DPI_EXTERN DPI_DLLESPEC
21
22#include "svdpi.h"
23
24#ifdef _WIN32
25#include <windows.h>
26#else
27#include <dlfcn.h>
28#include <stdio.h>
29#include <stdlib.h>
30#endif
31
32namespace {
33
34template <typename FnTy>
35FnTy resolveSvDpi(const char *name) {
36#ifdef _WIN32
37 // Resolve from the host simulator executable. This supports the Verilator
38 // flow where svDpi* symbols are exported by the generated simulator binary.
39 auto *host = GetModuleHandleA(nullptr);
40 void *sym =
41 host ? reinterpret_cast<void *>(GetProcAddress(host, name)) : nullptr;
42#else
43 // Look up in the process-global namespace provided by the host simulator.
44 // Use RTLD_DEFAULT first (simulator-exported/global symbols), then fall
45 // back to the main-program handle for environments with stricter policies.
46 void *sym = dlsym(RTLD_DEFAULT, name);
47 if (!sym) {
48 void *mainProg = dlopen(nullptr, RTLD_NOW);
49 if (mainProg)
50 sym = dlsym(mainProg, name);
51 }
52#endif
53 if (!sym) {
54#ifdef _WIN32
55 OutputDebugStringA(
56 "error: EsiCosimDpiServer failed to resolve required svdpi symbol '");
57 OutputDebugStringA(name);
58 OutputDebugStringA("'\n");
59 TerminateProcess(GetCurrentProcess(), 1);
60#else
61 fprintf(stderr,
62 "error: EsiCosimDpiServer failed to resolve required "
63 "svdpi symbol '%s'\n",
64 name);
65 fflush(stderr);
66 abort();
67#endif
68 }
69 return reinterpret_cast<FnTy>(sym);
70}
71
72} // namespace
73
74extern "C" int svDimensions(const svOpenArrayHandle h) {
75 using FnTy = int (*)(const svOpenArrayHandle);
76 static FnTy fn = resolveSvDpi<FnTy>("svDimensions");
77 return fn(h);
78}
79
80extern "C" void *svGetArrayPtr(const svOpenArrayHandle h) {
81 using FnTy = void *(*)(const svOpenArrayHandle);
82 static FnTy fn = resolveSvDpi<FnTy>("svGetArrayPtr");
83 return fn(h);
84}
85
86extern "C" int svSizeOfArray(const svOpenArrayHandle h) {
87 using FnTy = int (*)(const svOpenArrayHandle);
88 static FnTy fn = resolveSvDpi<FnTy>("svSizeOfArray");
89 return fn(h);
90}
91
92extern "C" int svSize(const svOpenArrayHandle h, int d) {
93 using FnTy = int (*)(const svOpenArrayHandle, int);
94 static FnTy fn = resolveSvDpi<FnTy>("svSize");
95 return fn(h, d);
96}
97
98extern "C" void *svGetArrElemPtr1(const svOpenArrayHandle h, int idx) {
99 using FnTy = void *(*)(const svOpenArrayHandle, int);
100 static FnTy fn = resolveSvDpi<FnTy>("svGetArrElemPtr1");
101 return fn(h, idx);
102}
void * svGetArrayPtr(const svOpenArrayHandle h)
int svSizeOfArray(const svOpenArrayHandle h)
int svSize(const svOpenArrayHandle h, int d)
void * svGetArrElemPtr1(const svOpenArrayHandle h, int idx)
int svDimensions(const svOpenArrayHandle h)
XXTERN typedef void * svOpenArrayHandle
Definition svdpi.h:133