1 // -*- mode: C++; c-file-style: "cc-mode" -*-
2 //*************************************************************************
3 //
4 // Code available from: https://verilator.org
5 //
6 // Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
7 // redistribute it and/or modify it under the terms of either the GNU
8 // Lesser General Public License Version 3 or the Perl Artistic License
9 // Version 2.0.
10 // SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
11 //
12 //=========================================================================
13 ///
14 /// \file
15 /// \brief Verilated DPI implementation code
16 ///
17 /// This file must be compiled and linked against all Verilated objects
18 /// that use the DPI.
19 ///
20 /// Declare any DPI routine inside Verilog to add this to the Makefile for
21 /// the linker.
22 ///
23 /// For documentation on the exported functions (named sv*) that are
24 /// implemented here, refer to the IEEE DPI chapter.
25 ///
26 //=========================================================================
27
28 #define VERILATOR_VERILATED_DPI_CPP_
29
30 #include "verilatedos.h"
31 #include "verilated_dpi.h"
32 #include "verilated_imp.h"
33
34 // On MSVC++ we need svdpi.h to declare exports, not imports
35 #define DPI_PROTOTYPES
36 #undef XXTERN
37 #define XXTERN DPI_EXTERN DPI_DLLESPEC
38 #undef EETERN
39 #define EETERN DPI_EXTERN DPI_DLLESPEC
40
41 #include "vltstd/svdpi.h"
42
43 //======================================================================
44 // Internal macros
45
46 #define VL_SVDPI_WARN_(...) VL_PRINTF_MT(__VA_ARGS__)
47
48 // Function requires a "context" in the import declaration
49 #define VL_SVDPI_CONTEXT_WARN_() \
50 VL_SVDPI_WARN_("%%Warning: DPI C Function called by Verilog DPI import with missing " \
51 "'context' keyword.\n")
52
53 //======================================================================
54 //======================================================================
55 //======================================================================
56 // DPI ROUTINES
57
svDpiVersion()58 const char* svDpiVersion() { return "1800-2005"; }
59
60 //======================================================================
61 // Bit-select utility functions.
62
svGetBitselBit(const svBitVecVal * sp,int bit)63 svBit svGetBitselBit(const svBitVecVal* sp, int bit) { return VL_BITRSHIFT_W(sp, bit) & 1; }
svGetBitselLogic(const svLogicVecVal * sp,int bit)64 svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
65 // Not VL_BITRSHIFT_W as sp is a different structure type
66 // Verilator doesn't support X/Z so only aval
67 return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1)
68 | (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1) << 1));
69 }
70
svPutBitselBit(svBitVecVal * dp,int bit,svBit s)71 void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(bit, dp, s); }
svPutBitselLogic(svLogicVecVal * dp,int bit,svLogic s)72 void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
73 // Verilator doesn't support X/Z so only aval
74 dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
75 | ((s & 1) << VL_BITBIT_I(bit)));
76 dp[VL_BITWORD_I(bit)].bval = ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
77 | ((s & 2) >> 1 << VL_BITBIT_I(bit)));
78 }
79
svGetPartselBit(svBitVecVal * dp,const svBitVecVal * sp,int lsb,int width)80 void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int lsb, int width) {
81 // See also VL_SEL_WWI
82 const int msb = lsb + width - 1;
83 const int word_shift = VL_BITWORD_I(lsb);
84 if (VL_BITBIT_I(lsb) == 0) {
85 // Just a word extract
86 for (int i = 0; i < VL_WORDS_I(width); ++i) dp[i] = sp[i + word_shift];
87 } else {
88 const int loffset = lsb & VL_SIZEBITS_I;
89 const int nbitsfromlow = 32 - loffset; // bits that end up in lword (know loffset!=0)
90 // Middle words
91 const int words = VL_WORDS_I(msb - lsb + 1);
92 for (int i = 0; i < words; ++i) {
93 dp[i] = sp[i + word_shift] >> loffset;
94 const int upperword = i + word_shift + 1;
95 if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
96 dp[i] |= sp[upperword] << nbitsfromlow;
97 }
98 }
99 }
100 // Clean result
101 dp[VL_WORDS_I(width) - 1] &= VL_MASK_I(width);
102 }
svGetPartselLogic(svLogicVecVal * dp,const svLogicVecVal * sp,int lsb,int width)103 void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lsb, int width) {
104 const int msb = lsb + width - 1;
105 const int word_shift = VL_BITWORD_I(lsb);
106 if (VL_BITBIT_I(lsb) == 0) {
107 // Just a word extract
108 for (int i = 0; i < VL_WORDS_I(width); ++i) dp[i] = sp[i + word_shift];
109 } else {
110 const int loffset = lsb & VL_SIZEBITS_I;
111 const int nbitsfromlow = 32 - loffset; // bits that end up in lword (know loffset!=0)
112 // Middle words
113 const int words = VL_WORDS_I(msb - lsb + 1);
114 for (int i = 0; i < words; ++i) {
115 dp[i].aval = sp[i + word_shift].aval >> loffset;
116 dp[i].bval = sp[i + word_shift].bval >> loffset;
117 const int upperword = i + word_shift + 1;
118 if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
119 dp[i].aval |= sp[upperword].aval << nbitsfromlow;
120 dp[i].bval |= sp[upperword].bval << nbitsfromlow;
121 }
122 }
123 }
124 // Clean result
125 dp[VL_WORDS_I(width) - 1].aval &= VL_MASK_I(width);
126 dp[VL_WORDS_I(width) - 1].bval &= VL_MASK_I(width);
127 }
svPutPartselBit(svBitVecVal * dp,const svBitVecVal s,int lbit,int width)128 void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width) {
129 // See also _vl_insert_WI
130 const int hbit = lbit + width - 1;
131 const int hoffset = VL_BITBIT_I(hbit);
132 const int loffset = VL_BITBIT_I(lbit);
133 if (hoffset == VL_SIZEBITS_I && loffset == 0) {
134 // Fast and common case, word based insertion
135 dp[VL_BITWORD_I(lbit)] = s;
136 } else {
137 const int hword = VL_BITWORD_I(hbit);
138 const int lword = VL_BITWORD_I(lbit);
139 if (hword == lword) { // know < 32 bits because above checks it
140 const IData insmask = (VL_MASK_I(hoffset - loffset + 1)) << loffset;
141 dp[lword] = (dp[lword] & ~insmask) | ((s << loffset) & insmask);
142 } else {
143 const IData hinsmask = (VL_MASK_I(hoffset - 0 + 1)) << 0;
144 const IData linsmask = (VL_MASK_I(31 - loffset + 1)) << loffset;
145 const int nbitsonright = 32 - loffset; // bits that end up in lword
146 dp[lword] = (dp[lword] & ~linsmask) | ((s << loffset) & linsmask);
147 dp[hword] = (dp[hword] & ~hinsmask) | ((s >> nbitsonright) & hinsmask);
148 }
149 }
150 }
151 // cppcheck-suppress passedByValue
svPutPartselLogic(svLogicVecVal * dp,const svLogicVecVal s,int lbit,int width)152 void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) {
153 const int hbit = lbit + width - 1;
154 const int hoffset = VL_BITBIT_I(hbit);
155 const int loffset = VL_BITBIT_I(lbit);
156 if (hoffset == VL_SIZEBITS_I && loffset == 0) {
157 // Fast and common case, word based insertion
158 dp[VL_BITWORD_I(lbit)].aval = s.aval;
159 dp[VL_BITWORD_I(lbit)].bval = s.bval;
160 } else {
161 const int hword = VL_BITWORD_I(hbit);
162 const int lword = VL_BITWORD_I(lbit);
163 if (hword == lword) { // know < 32 bits because above checks it
164 const IData insmask = (VL_MASK_I(hoffset - loffset + 1)) << loffset;
165 dp[lword].aval = (dp[lword].aval & ~insmask) | ((s.aval << loffset) & insmask);
166 dp[lword].bval = (dp[lword].bval & ~insmask) | ((s.bval << loffset) & insmask);
167 } else {
168 const IData hinsmask = (VL_MASK_I(hoffset - 0 + 1)) << 0;
169 const IData linsmask = (VL_MASK_I(31 - loffset + 1)) << loffset;
170 const int nbitsonright = 32 - loffset; // bits that end up in lword
171 dp[lword].aval = (dp[lword].aval & ~linsmask) | ((s.aval << loffset) & linsmask);
172 dp[lword].bval = (dp[lword].bval & ~linsmask) | ((s.bval << loffset) & linsmask);
173 dp[hword].aval = (dp[hword].aval & ~hinsmask) | ((s.aval >> nbitsonright) & hinsmask);
174 dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval >> nbitsonright) & hinsmask);
175 }
176 }
177 }
178
179 //======================================================================
180 // Open array internals
181
_vl_openhandle_varp(const svOpenArrayHandle h)182 static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
183 if (VL_UNLIKELY(!h)) {
184 VL_FATAL_MT(__FILE__, __LINE__, "",
185 "%%Error: DPI svOpenArrayHandle function called with nullptr handle");
186 }
187 const VerilatedDpiOpenVar* const varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
188 if (VL_UNLIKELY(!varp->magicOk())) {
189 VL_FATAL_MT(__FILE__, __LINE__, "",
190 "%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
191 }
192 return varp;
193 }
194
195 //======================================================================
196 // Open array querying functions
197
svLeft(const svOpenArrayHandle h,int d)198 int svLeft(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->left(d); }
svRight(const svOpenArrayHandle h,int d)199 int svRight(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->right(d); }
svLow(const svOpenArrayHandle h,int d)200 int svLow(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->low(d); }
svHigh(const svOpenArrayHandle h,int d)201 int svHigh(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->high(d); }
svIncrement(const svOpenArrayHandle h,int d)202 int svIncrement(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->increment(d); }
svSize(const svOpenArrayHandle h,int d)203 int svSize(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->elements(d); }
svDimensions(const svOpenArrayHandle h)204 int svDimensions(const svOpenArrayHandle h) { return _vl_openhandle_varp(h)->udims(); }
205
206 // Return pointer to open array data, or nullptr if not in IEEE standard C layout
svGetArrayPtr(const svOpenArrayHandle h)207 void* svGetArrayPtr(const svOpenArrayHandle h) {
208 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
209 if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
210 return varp->datap();
211 }
212 // Return size of open array, or 0 if not in IEEE standard C layout
svSizeOfArray(const svOpenArrayHandle h)213 int svSizeOfArray(const svOpenArrayHandle h) {
214 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
215 if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0;
216 // Truncate 64 bits to int; DPI is limited to 4GB
217 return static_cast<int>(varp->totalSize());
218 }
219
220 //======================================================================
221 // Open array access internals
222
_vl_sv_adjusted_datap(const VerilatedDpiOpenVar * varp,int nargs,int indx1,int indx2,int indx3)223 static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, int indx1,
224 int indx2, int indx3) {
225 void* datap = varp->datap();
226 if (VL_UNLIKELY(nargs != varp->udims())) {
227 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function called on"
228 " %d dimensional array using %d dimensional function.\n",
229 varp->udims(), nargs);
230 return nullptr;
231 }
232 if (nargs >= 1) {
233 datap = varp->datapAdjustIndex(datap, 1, indx1);
234 if (VL_UNLIKELY(!datap)) {
235 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 1 "
236 "out of bounds; %d outside [%d:%d].\n",
237 indx1, varp->left(1), varp->right(1));
238 return nullptr;
239 }
240 }
241 if (nargs >= 2) {
242 datap = varp->datapAdjustIndex(datap, 2, indx2);
243 if (VL_UNLIKELY(!datap)) {
244 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 2 "
245 "out of bounds; %d outside [%d:%d].\n",
246 indx2, varp->left(2), varp->right(2));
247 return nullptr;
248 }
249 }
250 if (nargs >= 3) {
251 datap = varp->datapAdjustIndex(datap, 3, indx3);
252 if (VL_UNLIKELY(!datap)) {
253 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 3 "
254 "out of bounds; %d outside [%d:%d].\n",
255 indx1, varp->left(3), varp->right(3));
256 return nullptr;
257 }
258 }
259 return datap;
260 }
261
262 // Return pointer to simulator open array element, or nullptr if outside range
_vl_svGetArrElemPtr(const svOpenArrayHandle h,int nargs,int indx1,int indx2,int indx3)263 static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2,
264 int indx3) VL_MT_SAFE {
265 const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
266 if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
267 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
268 return datap;
269 }
270
271 // Copy to user bit array from simulator open array
_vl_svGetBitArrElemVecVal(svBitVecVal * d,const svOpenArrayHandle s,int nargs,int indx1,int indx2,int indx3)272 static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int nargs,
273 int indx1, int indx2, int indx3) VL_MT_SAFE {
274 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
275 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
276 if (VL_UNLIKELY(!datap)) return;
277 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
278 case VLVT_UINT8: d[0] = *(reinterpret_cast<CData*>(datap)); return;
279 case VLVT_UINT16: d[0] = *(reinterpret_cast<SData*>(datap)); return;
280 case VLVT_UINT32: d[0] = *(reinterpret_cast<IData*>(datap)); return;
281 case VLVT_UINT64: {
282 VlWide<2> lwp;
283 VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
284 d[0] = lwp[0];
285 d[1] = lwp[1];
286 break;
287 }
288 case VLVT_WDATA: {
289 WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
290 for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
291 return;
292 }
293 default: // LCOV_EXCL_START // Errored earlier
294 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
295 varp->vltype());
296 return; // LCOV_EXCL_STOP
297 }
298 }
299 // Copy to user logic array from simulator open array
_vl_svGetLogicArrElemVecVal(svLogicVecVal * d,const svOpenArrayHandle s,int nargs,int indx1,int indx2,int indx3)300 static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int nargs,
301 int indx1, int indx2, int indx3) VL_MT_SAFE {
302 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
303 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
304 if (VL_UNLIKELY(!datap)) return;
305 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
306 case VLVT_UINT8:
307 d[0].aval = *(reinterpret_cast<CData*>(datap));
308 d[0].bval = 0;
309 return;
310 case VLVT_UINT16:
311 d[0].aval = *(reinterpret_cast<SData*>(datap));
312 d[0].bval = 0;
313 return;
314 case VLVT_UINT32:
315 d[0].aval = *(reinterpret_cast<IData*>(datap));
316 d[0].bval = 0;
317 return;
318 case VLVT_UINT64: {
319 VlWide<2> lwp;
320 VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
321 d[0].aval = lwp[0];
322 d[0].bval = 0;
323 d[1].aval = lwp[1];
324 d[1].bval = 0;
325 break;
326 }
327 case VLVT_WDATA: {
328 WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
329 for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) {
330 d[i].aval = wdatap[i];
331 d[i].bval = 0;
332 }
333 return;
334 }
335 default: // LCOV_EXCL_START // Errored earlier
336 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
337 varp->vltype());
338 return; // LCOV_EXCL_STOP
339 }
340 }
341
342 // Copy to simulator open array from from user bit array
_vl_svPutBitArrElemVecVal(const svOpenArrayHandle d,const svBitVecVal * s,int nargs,int indx1,int indx2,int indx3)343 static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int nargs,
344 int indx1, int indx2, int indx3) VL_MT_SAFE {
345 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
346 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
347 if (VL_UNLIKELY(!datap)) return;
348 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
349 case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0]; return;
350 case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0]; return;
351 case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0]; return;
352 case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = VL_SET_QII(s[1], s[0]); break;
353 case VLVT_WDATA: {
354 WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
355 for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
356 return;
357 }
358 default: // LCOV_EXCL_START // Errored earlier
359 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
360 varp->vltype());
361 return; // LCOV_EXCL_STOP
362 }
363 }
364 // Copy to simulator open array from from user logic array
_vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d,const svLogicVecVal * s,int nargs,int indx1,int indx2,int indx3)365 static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
366 int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
367 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
368 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
369 if (VL_UNLIKELY(!datap)) return;
370 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
371 case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
372 case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0].aval; return;
373 case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0].aval; return;
374 case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = VL_SET_QII(s[1].aval, s[0].aval); break;
375 case VLVT_WDATA: {
376 WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
377 for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
378 return;
379 }
380 default: // LCOV_EXCL_START // Errored earlier
381 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
382 varp->vltype());
383 return; // LCOV_EXCL_STOP
384 }
385 }
386
387 // Return bit from simulator open array
_vl_svGetBitArrElem(const svOpenArrayHandle s,int nargs,int indx1,int indx2,int indx3,int)388 static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1, int indx2,
389 int indx3, int) VL_MT_SAFE {
390 // One extra index supported, as need bit number
391 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
392 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
393 if (VL_UNLIKELY(!datap)) return 0;
394 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
395 case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap))) & 1;
396 default: // LCOV_EXCL_START // Errored earlier
397 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
398 varp->vltype());
399 return 0; // LCOV_EXCL_STOP
400 }
401 }
402 // Update simulator open array from bit
_vl_svPutBitArrElem(const svOpenArrayHandle d,svBit value,int nargs,int indx1,int indx2,int indx3,int)403 static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int nargs, int indx1,
404 int indx2, int indx3, int) VL_MT_SAFE {
405 // One extra index supported, as need bit number
406 value &= 1; // Make sure clean
407 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
408 void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
409 if (VL_UNLIKELY(!datap)) return;
410 switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
411 case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = value; return;
412 default: // LCOV_EXCL_START // Errored earlier
413 VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
414 varp->vltype());
415 return; // LCOV_EXCL_STOP
416 }
417 }
418
419 //======================================================================
420 // DPI accessors that simply call above functions
421
svGetArrElemPtr(const svOpenArrayHandle h,int indx1,...)422 void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
423 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
424 void* datap;
425 va_list ap;
426 va_start(ap, indx1);
427 // va_arg is a macro, so need temporaries as used below
428 switch (varp->udims()) {
429 case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
430 case 2: {
431 const int indx2 = va_arg(ap, int);
432 datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
433 break;
434 }
435 case 3: {
436 const int indx2 = va_arg(ap, int);
437 const int indx3 = va_arg(ap, int);
438 datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
439 break;
440 }
441 default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break; // Will error
442 }
443 va_end(ap);
444 return datap;
445 }
svGetArrElemPtr1(const svOpenArrayHandle h,int indx1)446 void* svGetArrElemPtr1(const svOpenArrayHandle h, int indx1) {
447 return _vl_svGetArrElemPtr(h, 1, indx1, 0, 0);
448 }
svGetArrElemPtr2(const svOpenArrayHandle h,int indx1,int indx2)449 void* svGetArrElemPtr2(const svOpenArrayHandle h, int indx1, int indx2) {
450 return _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
451 }
svGetArrElemPtr3(const svOpenArrayHandle h,int indx1,int indx2,int indx3)452 void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx3) {
453 return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
454 }
455
svPutBitArrElemVecVal(const svOpenArrayHandle d,const svBitVecVal * s,int indx1,...)456 void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) {
457 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
458 va_list ap;
459 va_start(ap, indx1);
460 switch (varp->udims()) {
461 case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
462 case 2: {
463 const int indx2 = va_arg(ap, int);
464 _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
465 break;
466 }
467 case 3: {
468 const int indx2 = va_arg(ap, int);
469 const int indx3 = va_arg(ap, int);
470 _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
471 break;
472 }
473 default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
474 }
475 va_end(ap);
476 }
svPutBitArrElem1VecVal(const svOpenArrayHandle d,const svBitVecVal * s,int indx1)477 void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1) {
478 _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0);
479 }
svPutBitArrElem2VecVal(const svOpenArrayHandle d,const svBitVecVal * s,int indx1,int indx2)480 void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1,
481 int indx2) {
482 _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
483 }
svPutBitArrElem3VecVal(const svOpenArrayHandle d,const svBitVecVal * s,int indx1,int indx2,int indx3)484 void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2,
485 int indx3) {
486 _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
487 }
svPutLogicArrElemVecVal(const svOpenArrayHandle d,const svLogicVecVal * s,int indx1,...)488 void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) {
489 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
490 va_list ap;
491 va_start(ap, indx1);
492 switch (varp->udims()) {
493 case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
494 case 2: {
495 const int indx2 = va_arg(ap, int);
496 _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
497 break;
498 }
499 case 3: {
500 const int indx2 = va_arg(ap, int);
501 const int indx3 = va_arg(ap, int);
502 _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
503 break;
504 }
505 default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
506 }
507 va_end(ap);
508 }
svPutLogicArrElem1VecVal(const svOpenArrayHandle d,const svLogicVecVal * s,int indx1)509 void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1) {
510 _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
511 }
svPutLogicArrElem2VecVal(const svOpenArrayHandle d,const svLogicVecVal * s,int indx1,int indx2)512 void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
513 int indx2) {
514 _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
515 }
svPutLogicArrElem3VecVal(const svOpenArrayHandle d,const svLogicVecVal * s,int indx1,int indx2,int indx3)516 void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
517 int indx2, int indx3) {
518 _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
519 }
520
521 //======================================================================
522 // From simulator storage into user space
523
svGetBitArrElemVecVal(svBitVecVal * d,const svOpenArrayHandle s,int indx1,...)524 void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
525 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
526 va_list ap;
527 va_start(ap, indx1);
528 switch (varp->udims()) {
529 case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
530 case 2: {
531 const int indx2 = va_arg(ap, int);
532 _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
533 break;
534 }
535 case 3: {
536 const int indx2 = va_arg(ap, int);
537 const int indx3 = va_arg(ap, int);
538 _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
539 break;
540 }
541 default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
542 }
543 va_end(ap);
544 }
svGetBitArrElem1VecVal(svBitVecVal * d,const svOpenArrayHandle s,int indx1)545 void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1) {
546 _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0);
547 }
svGetBitArrElem2VecVal(svBitVecVal * d,const svOpenArrayHandle s,int indx1,int indx2)548 void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
549 _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
550 }
svGetBitArrElem3VecVal(svBitVecVal * d,const svOpenArrayHandle s,int indx1,int indx2,int indx3)551 void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
552 int indx3) {
553 _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
554 }
svGetLogicArrElemVecVal(svLogicVecVal * d,const svOpenArrayHandle s,int indx1,...)555 void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
556 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
557 va_list ap;
558 va_start(ap, indx1);
559 switch (varp->udims()) {
560 case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
561 case 2: {
562 const int indx2 = va_arg(ap, int);
563 _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
564 break;
565 }
566 case 3: {
567 const int indx2 = va_arg(ap, int);
568 const int indx3 = va_arg(ap, int);
569 _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
570 break;
571 }
572 default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
573 }
574 va_end(ap);
575 }
svGetLogicArrElem1VecVal(svLogicVecVal * d,const svOpenArrayHandle s,int indx1)576 void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1) {
577 _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
578 }
svGetLogicArrElem2VecVal(svLogicVecVal * d,const svOpenArrayHandle s,int indx1,int indx2)579 void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
580 _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
581 }
svGetLogicArrElem3VecVal(svLogicVecVal * d,const svOpenArrayHandle s,int indx1,int indx2,int indx3)582 void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
583 int indx3) {
584 _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
585 }
586
svGetBitArrElem(const svOpenArrayHandle s,int indx1,...)587 svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
588 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
589 svBit out;
590 va_list ap;
591 va_start(ap, indx1);
592 switch (varp->udims()) {
593 case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
594 case 2: {
595 const int indx2 = va_arg(ap, int);
596 out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
597 break;
598 }
599 case 3: {
600 const int indx2 = va_arg(ap, int);
601 const int indx3 = va_arg(ap, int);
602 out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
603 break;
604 }
605 default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
606 }
607 va_end(ap);
608 return out;
609 }
svGetBitArrElem1(const svOpenArrayHandle s,int indx1)610 svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) {
611 return _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0);
612 }
svGetBitArrElem2(const svOpenArrayHandle s,int indx1,int indx2)613 svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
614 return _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
615 }
svGetBitArrElem3(const svOpenArrayHandle s,int indx1,int indx2,int indx3)616 svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
617 return _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
618 }
svGetLogicArrElem(const svOpenArrayHandle s,int indx1,...)619 svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
620 // Verilator doesn't support X/Z so can just call Bit version
621 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
622 svBit out;
623 va_list ap;
624 va_start(ap, indx1);
625 switch (varp->udims()) {
626 case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
627 case 2: {
628 const int indx2 = va_arg(ap, int);
629 out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
630 break;
631 }
632 case 3: {
633 const int indx2 = va_arg(ap, int);
634 const int indx3 = va_arg(ap, int);
635 out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
636 break;
637 }
638 default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
639 }
640 va_end(ap);
641 return out;
642 }
svGetLogicArrElem1(const svOpenArrayHandle s,int indx1)643 svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) {
644 // Verilator doesn't support X/Z so can just call Bit version
645 return svGetBitArrElem1(s, indx1);
646 }
svGetLogicArrElem2(const svOpenArrayHandle s,int indx1,int indx2)647 svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
648 // Verilator doesn't support X/Z so can just call Bit version
649 return svGetBitArrElem2(s, indx1, indx2);
650 }
svGetLogicArrElem3(const svOpenArrayHandle s,int indx1,int indx2,int indx3)651 svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
652 // Verilator doesn't support X/Z so can just call Bit version
653 return svGetBitArrElem3(s, indx1, indx2, indx3);
654 }
655
svPutBitArrElem(const svOpenArrayHandle d,svBit value,int indx1,...)656 void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
657 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
658 va_list ap;
659 va_start(ap, indx1);
660 switch (varp->udims()) {
661 case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
662 case 2: {
663 const int indx2 = va_arg(ap, int);
664 _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
665 break;
666 }
667 case 3: {
668 const int indx2 = va_arg(ap, int);
669 const int indx3 = va_arg(ap, int);
670 _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
671 break;
672 }
673 default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
674 }
675 va_end(ap);
676 }
svPutBitArrElem1(const svOpenArrayHandle d,svBit value,int indx1)677 void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) {
678 _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0);
679 }
svPutBitArrElem2(const svOpenArrayHandle d,svBit value,int indx1,int indx2)680 void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) {
681 _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
682 }
svPutBitArrElem3(const svOpenArrayHandle d,svBit value,int indx1,int indx2,int indx3)683 void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) {
684 _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
685 }
svPutLogicArrElem(const svOpenArrayHandle d,svLogic value,int indx1,...)686 void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) {
687 // Verilator doesn't support X/Z so can just call Bit version
688 const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
689 va_list ap;
690 va_start(ap, indx1);
691 switch (varp->udims()) {
692 case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
693 case 2: {
694 const int indx2 = va_arg(ap, int);
695 _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
696 break;
697 }
698 case 3: {
699 const int indx2 = va_arg(ap, int);
700 const int indx3 = va_arg(ap, int);
701 _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
702 break;
703 }
704 default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
705 }
706 va_end(ap);
707 }
svPutLogicArrElem1(const svOpenArrayHandle d,svLogic value,int indx1)708 void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
709 // Verilator doesn't support X/Z so can just call Bit version
710 svPutBitArrElem1(d, value, indx1);
711 }
svPutLogicArrElem2(const svOpenArrayHandle d,svLogic value,int indx1,int indx2)712 void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
713 // Verilator doesn't support X/Z so can just call Bit version
714 svPutBitArrElem2(d, value, indx1, indx2);
715 }
svPutLogicArrElem3(const svOpenArrayHandle d,svLogic value,int indx1,int indx2,int indx3)716 void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2,
717 int indx3) {
718 // Verilator doesn't support X/Z so can just call Bit version
719 svPutBitArrElem3(d, value, indx1, indx2, indx3);
720 }
721
722 //======================================================================
723 // Functions for working with DPI context
724
svGetScope()725 svScope svGetScope() {
726 if (VL_UNLIKELY(!Verilated::dpiInContext())) {
727 VL_SVDPI_CONTEXT_WARN_();
728 return nullptr;
729 }
730 // NOLINTNEXTLINE(google-readability-casting)
731 return (svScope)(Verilated::dpiScope());
732 }
733
svSetScope(const svScope scope)734 svScope svSetScope(const svScope scope) {
735 const VerilatedScope* const prevScopep = Verilated::dpiScope();
736 const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
737 Verilated::dpiScope(vscopep);
738 // NOLINTNEXTLINE(google-readability-casting)
739 return (svScope)(prevScopep);
740 }
741
svGetNameFromScope(const svScope scope)742 const char* svGetNameFromScope(const svScope scope) {
743 const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
744 return vscopep->name();
745 }
746
svGetScopeFromName(const char * scopeName)747 svScope svGetScopeFromName(const char* scopeName) {
748 // NOLINTNEXTLINE(google-readability-casting)
749 return (svScope)(Verilated::threadContextp()->scopeFind(scopeName));
750 }
751
svPutUserData(const svScope scope,void * userKey,void * userData)752 int svPutUserData(const svScope scope, void* userKey, void* userData) {
753 VerilatedImp::userInsert(scope, userKey, userData);
754 return 0;
755 }
756
svGetUserData(const svScope scope,void * userKey)757 void* svGetUserData(const svScope scope, void* userKey) {
758 return VerilatedImp::userFind(scope, userKey);
759 }
760
svGetCallerInfo(const char ** fileNamepp,int * lineNumberp)761 int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
762 if (VL_UNLIKELY(!Verilated::dpiInContext())) {
763 VL_SVDPI_CONTEXT_WARN_();
764 return false;
765 }
766 if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep(); // thread local
767 if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno(); // thread local
768 return true;
769 }
770
771 //======================================================================
772 // Disables
773
svIsDisabledState()774 int svIsDisabledState() {
775 return 0; // Disables not implemented
776 }
777
svAckDisabledState()778 void svAckDisabledState() {
779 // Disables not implemented
780 }
781