Verilator

Форк
0
/
verilated_dpi.cpp 
812 строк · 32.6 Кб
1
// -*- mode: C++; c-file-style: "cc-mode" -*-
2
//*************************************************************************
3
//
4
// Code available from: https://verilator.org
5
//
6
// Copyright 2009-2024 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

32
#include "verilated_dpi.h"
33

34
#include "verilated_imp.h"
35

36
// On MSVC++ we need svdpi.h to declare exports, not imports
37
#define DPI_PROTOTYPES
38
#undef XXTERN
39
#define XXTERN DPI_EXTERN DPI_DLLESPEC
40
#undef EETERN
41
#define EETERN DPI_EXTERN DPI_DLLESPEC
42

43
#include "vltstd/svdpi.h"
44

45
//======================================================================
46
// Internal macros
47

48
#define VL_SVDPI_WARN_(...) VL_PRINTF_MT(__VA_ARGS__)
49

50
// Function requires a "context" in the import declaration
51
#define VL_SVDPI_CONTEXT_WARN_() \
52
    VL_SVDPI_WARN_("%%Warning: DPI C Function called by Verilog DPI import with missing " \
53
                   "'context' keyword.\n")
54

55
//======================================================================
56
//======================================================================
57
//======================================================================
58
// DPI ROUTINES
59

60
const char* svDpiVersion() { return "1800-2005"; }
61

62
//======================================================================
63
// Bit-select utility functions.
64

65
svBit svGetBitselBit(const svBitVecVal* sp, int bit) { return VL_BITRSHIFT_W(sp, bit) & 1; }
66
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
67
    // Not VL_BITRSHIFT_W as sp is a different structure type
68
    // Verilator doesn't support X/Z so only aval
69
    return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1)
70
            | (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1) << 1));
71
}
72

73
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(bit, dp, s); }
74
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
75
    // Verilator doesn't support X/Z so only aval
76
    dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
77
                                  | ((s & 1) << VL_BITBIT_I(bit)));
78
    dp[VL_BITWORD_I(bit)].bval = ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
79
                                  | ((s & 2) >> 1 << VL_BITBIT_I(bit)));
80
}
81

82
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int lsb, int width) {
83
    // See also VL_SEL_WWI
84
    const int msb = lsb + width - 1;
85
    const int word_shift = VL_BITWORD_I(lsb);
86
    if (VL_BITBIT_I(lsb) == 0) {
87
        // Just a word extract
88
        for (int i = 0; i < VL_WORDS_I(width); ++i) dp[i] = sp[i + word_shift];
89
    } else {
90
        const int loffset = lsb & VL_SIZEBITS_I;
91
        const int nbitsfromlow = 32 - loffset;  // bits that end up in lword (know loffset!=0)
92
        // Middle words
93
        const int words = VL_WORDS_I(msb - lsb + 1);
94
        for (int i = 0; i < words; ++i) {
95
            dp[i] = sp[i + word_shift] >> loffset;
96
            const int upperword = i + word_shift + 1;
97
            if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
98
                dp[i] |= sp[upperword] << nbitsfromlow;
99
            }
100
        }
101
    }
102
    // Clean result
103
    dp[VL_WORDS_I(width) - 1] &= VL_MASK_I(width);
104
}
105
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lsb, int width) {
106
    const int msb = lsb + width - 1;
107
    const int word_shift = VL_BITWORD_I(lsb);
108
    if (VL_BITBIT_I(lsb) == 0) {
109
        // Just a word extract
110
        for (int i = 0; i < VL_WORDS_I(width); ++i) dp[i] = sp[i + word_shift];
111
    } else {
112
        const int loffset = lsb & VL_SIZEBITS_I;
113
        const int nbitsfromlow = 32 - loffset;  // bits that end up in lword (know loffset!=0)
114
        // Middle words
115
        const int words = VL_WORDS_I(msb - lsb + 1);
116
        for (int i = 0; i < words; ++i) {
117
            dp[i].aval = sp[i + word_shift].aval >> loffset;
118
            dp[i].bval = sp[i + word_shift].bval >> loffset;
119
            const int upperword = i + word_shift + 1;
120
            if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
121
                dp[i].aval |= sp[upperword].aval << nbitsfromlow;
122
                dp[i].bval |= sp[upperword].bval << nbitsfromlow;
123
            }
124
        }
125
    }
126
    // Clean result
127
    dp[VL_WORDS_I(width) - 1].aval &= VL_MASK_I(width);
128
    dp[VL_WORDS_I(width) - 1].bval &= VL_MASK_I(width);
129
}
130
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width) {
131
    // See also _vl_insert_WI
132
    const int hbit = lbit + width - 1;
133
    const int hoffset = VL_BITBIT_I(hbit);
134
    const int loffset = VL_BITBIT_I(lbit);
135
    if (hoffset == VL_SIZEBITS_I && loffset == 0) {
136
        // Fast and common case, word based insertion
137
        dp[VL_BITWORD_I(lbit)] = s;
138
    } else {
139
        const int hword = VL_BITWORD_I(hbit);
140
        const int lword = VL_BITWORD_I(lbit);
141
        if (hword == lword) {  // know < 32 bits because above checks it
142
            const IData insmask = (VL_MASK_I(hoffset - loffset + 1)) << loffset;
143
            dp[lword] = (dp[lword] & ~insmask) | ((s << loffset) & insmask);
144
        } else {
145
            const IData hinsmask = (VL_MASK_I(hoffset - 0 + 1)) << 0;
146
            const IData linsmask = (VL_MASK_I(31 - loffset + 1)) << loffset;
147
            const int nbitsonright = 32 - loffset;  // bits that end up in lword
148
            dp[lword] = (dp[lword] & ~linsmask) | ((s << loffset) & linsmask);
149
            dp[hword] = (dp[hword] & ~hinsmask) | ((s >> nbitsonright) & hinsmask);
150
        }
151
    }
152
}
153
// cppcheck-suppress passedByValue
154
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) {
155
    const int hbit = lbit + width - 1;
156
    const int hoffset = VL_BITBIT_I(hbit);
157
    const int loffset = VL_BITBIT_I(lbit);
158
    if (hoffset == VL_SIZEBITS_I && loffset == 0) {
159
        // Fast and common case, word based insertion
160
        dp[VL_BITWORD_I(lbit)].aval = s.aval;
161
        dp[VL_BITWORD_I(lbit)].bval = s.bval;
162
    } else {
163
        const int hword = VL_BITWORD_I(hbit);
164
        const int lword = VL_BITWORD_I(lbit);
165
        if (hword == lword) {  // know < 32 bits because above checks it
166
            const IData insmask = (VL_MASK_I(hoffset - loffset + 1)) << loffset;
167
            dp[lword].aval = (dp[lword].aval & ~insmask) | ((s.aval << loffset) & insmask);
168
            dp[lword].bval = (dp[lword].bval & ~insmask) | ((s.bval << loffset) & insmask);
169
        } else {
170
            const IData hinsmask = (VL_MASK_I(hoffset - 0 + 1)) << 0;
171
            const IData linsmask = (VL_MASK_I(31 - loffset + 1)) << loffset;
172
            const int nbitsonright = 32 - loffset;  // bits that end up in lword
173
            dp[lword].aval = (dp[lword].aval & ~linsmask) | ((s.aval << loffset) & linsmask);
174
            dp[lword].bval = (dp[lword].bval & ~linsmask) | ((s.bval << loffset) & linsmask);
175
            dp[hword].aval = (dp[hword].aval & ~hinsmask) | ((s.aval >> nbitsonright) & hinsmask);
176
            dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval >> nbitsonright) & hinsmask);
177
        }
178
    }
179
}
180

181
//======================================================================
182
// Open array internals
183

184
static const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) VL_MT_SAFE {
185
    if (VL_UNLIKELY(!h)) {
186
        VL_FATAL_MT(__FILE__, __LINE__, "",
187
                    "%%Error: DPI svOpenArrayHandle function called with nullptr handle");
188
    }
189
    const VerilatedDpiOpenVar* const varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
190
    if (VL_UNLIKELY(!varp->magicOk())) {
191
        VL_FATAL_MT(__FILE__, __LINE__, "",
192
                    "%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
193
    }
194
    return varp;
195
}
196

197
//======================================================================
198
// Open array querying functions
199

200
int svLeft(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->left(d); }
201
int svRight(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->right(d); }
202
int svLow(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->low(d); }
203
int svHigh(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->high(d); }
204
int svIncrement(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->increment(d); }
205
int svSize(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->elements(d); }
206
int svDimensions(const svOpenArrayHandle h) { return _vl_openhandle_varp(h)->udims(); }
207

208
// Return pointer to open array data, or nullptr if not in IEEE standard C layout
209
void* svGetArrayPtr(const svOpenArrayHandle h) {
210
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
211
    if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
212
    return varp->datap();
213
}
214
// Return size of open array, or 0 if not in IEEE standard C layout
215
int svSizeOfArray(const svOpenArrayHandle h) {
216
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
217
    if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0;
218
    // Truncate 64 bits to int; DPI is limited to 4GB
219
    return static_cast<int>(varp->totalSize());
220
}
221

222
//======================================================================
223
// Open array access internals
224

225
static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, int indx1,
226
                                   int indx2, int indx3) VL_MT_SAFE {
227
    void* datap = varp->datap();
228
    if (VL_UNLIKELY(nargs != varp->udims())) {
229
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function called on"
230
                       " %d dimensional array using %d dimensional function.\n",
231
                       varp->udims(), nargs);
232
        return nullptr;
233
    }
234
    if (nargs >= 1) {
235
        datap = varp->datapAdjustIndex(datap, 1, indx1);
236
        if (VL_UNLIKELY(!datap)) {
237
            VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 1 "
238
                           "out of bounds; %d outside [%d:%d].\n",
239
                           indx1, varp->left(1), varp->right(1));
240
            return nullptr;
241
        }
242
    }
243
    if (nargs >= 2) {
244
        datap = varp->datapAdjustIndex(datap, 2, indx2);
245
        if (VL_UNLIKELY(!datap)) {
246
            VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 2 "
247
                           "out of bounds; %d outside [%d:%d].\n",
248
                           indx2, varp->left(2), varp->right(2));
249
            return nullptr;
250
        }
251
    }
252
    if (nargs >= 3) {
253
        datap = varp->datapAdjustIndex(datap, 3, indx3);
254
        if (VL_UNLIKELY(!datap)) {
255
            VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function index 3 "
256
                           "out of bounds; %d outside [%d:%d].\n",
257
                           indx1, varp->left(3), varp->right(3));
258
            return nullptr;
259
        }
260
    }
261
    return datap;
262
}
263

264
// Return pointer to simulator open array element, or nullptr if outside range
265
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2,
266
                                 int indx3) VL_MT_SAFE {
267
    const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
268
    if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
269
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
270
    return datap;
271
}
272

273
// Copy to user bit array from simulator open array
274
static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int nargs,
275
                                      int indx1, int indx2, int indx3) VL_MT_SAFE {
276
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
277
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
278
    if (VL_UNLIKELY(!datap)) return;
279
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
280
    case VLVT_UINT8: d[0] = *(reinterpret_cast<CData*>(datap)); return;
281
    case VLVT_UINT16: d[0] = *(reinterpret_cast<SData*>(datap)); return;
282
    case VLVT_UINT32: d[0] = *(reinterpret_cast<IData*>(datap)); return;
283
    case VLVT_UINT64: {
284
        VlWide<2> lwp;
285
        VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
286
        d[0] = lwp[0];
287
        d[1] = lwp[1];
288
        break;
289
    }
290
    case VLVT_WDATA: {
291
        WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
292
        for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
293
        return;
294
    }
295
    default:  // LCOV_EXCL_START  // Errored earlier
296
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
297
                       varp->vltype());
298
        return;  // LCOV_EXCL_STOP
299
    }
300
}
301
// Copy to user logic array from simulator open array
302
static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int nargs,
303
                                        int indx1, int indx2, int indx3) VL_MT_SAFE {
304
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
305
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
306
    if (VL_UNLIKELY(!datap)) return;
307
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
308
    case VLVT_UINT8:
309
        d[0].aval = *(reinterpret_cast<CData*>(datap));
310
        d[0].bval = 0;
311
        return;
312
    case VLVT_UINT16:
313
        d[0].aval = *(reinterpret_cast<SData*>(datap));
314
        d[0].bval = 0;
315
        return;
316
    case VLVT_UINT32:
317
        d[0].aval = *(reinterpret_cast<IData*>(datap));
318
        d[0].bval = 0;
319
        return;
320
    case VLVT_UINT64: {
321
        VlWide<2> lwp;
322
        VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
323
        d[0].aval = lwp[0];
324
        d[0].bval = 0;
325
        d[1].aval = lwp[1];
326
        d[1].bval = 0;
327
        break;
328
    }
329
    case VLVT_WDATA: {
330
        WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
331
        for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) {
332
            d[i].aval = wdatap[i];
333
            d[i].bval = 0;
334
        }
335
        return;
336
    }
337
    default:  // LCOV_EXCL_START  // Errored earlier
338
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
339
                       varp->vltype());
340
        return;  // LCOV_EXCL_STOP
341
    }
342
}
343

344
// Copy to simulator open array from from user bit array
345
static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int nargs,
346
                                      int indx1, int indx2, int indx3) VL_MT_SAFE {
347
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
348
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
349
    if (VL_UNLIKELY(!datap)) return;
350
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
351
    case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0]; return;
352
    case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0]; return;
353
    case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0]; return;
354
    case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = VL_SET_QII(s[1], s[0]); break;
355
    case VLVT_WDATA: {
356
        WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
357
        for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
358
        return;
359
    }
360
    default:  // LCOV_EXCL_START  // Errored earlier
361
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
362
                       varp->vltype());
363
        return;  // LCOV_EXCL_STOP
364
    }
365
}
366
// Copy to simulator open array from from user logic array
367
static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
368
                                        int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
369
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
370
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
371
    if (VL_UNLIKELY(!datap)) return;
372
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
373
    case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
374
    case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0].aval; return;
375
    case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0].aval; return;
376
    case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = VL_SET_QII(s[1].aval, s[0].aval); break;
377
    case VLVT_WDATA: {
378
        WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
379
        for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
380
        return;
381
    }
382
    default:  // LCOV_EXCL_START  // Errored earlier
383
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
384
                       varp->vltype());
385
        return;  // LCOV_EXCL_STOP
386
    }
387
}
388

389
// Return bit from simulator open array
390
static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1, int indx2,
391
                                 int indx3, int) VL_MT_SAFE {
392
    // One extra index supported, as need bit number
393
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
394
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
395
    if (VL_UNLIKELY(!datap)) return 0;
396
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
397
    case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap))) & 1;
398
    default:  // LCOV_EXCL_START  // Errored earlier
399
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
400
                       varp->vltype());
401
        return 0;  // LCOV_EXCL_STOP
402
    }
403
}
404
// Update simulator open array from bit
405
static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int nargs, int indx1,
406
                                int indx2, int indx3, int) VL_MT_SAFE {
407
    // One extra index supported, as need bit number
408
    value &= 1;  // Make sure clean
409
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
410
    void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
411
    if (VL_UNLIKELY(!datap)) return;
412
    switch (varp->vltype()) {  // LCOV_EXCL_BR_LINE
413
    case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = value; return;
414
    default:  // LCOV_EXCL_START  // Errored earlier
415
        VL_SVDPI_WARN_("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
416
                       varp->vltype());
417
        return;  // LCOV_EXCL_STOP
418
    }
419
}
420

421
//======================================================================
422
// DPI accessors that call above functions
423

424
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
425
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
426
    void* datap;
427
    va_list ap;
428
    va_start(ap, indx1);
429
    // va_arg is a macro, so need temporaries as used below
430
    switch (varp->udims()) {
431
    case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
432
    case 2: {
433
        const int indx2 = va_arg(ap, int);
434
        datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
435
        break;
436
    }
437
    case 3: {
438
        const int indx2 = va_arg(ap, int);
439
        const int indx3 = va_arg(ap, int);
440
        datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
441
        break;
442
    }
443
    default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break;  // Will error
444
    }
445
    va_end(ap);
446
    return datap;
447
}
448
void* svGetArrElemPtr1(const svOpenArrayHandle h, int indx1) {
449
    return _vl_svGetArrElemPtr(h, 1, indx1, 0, 0);
450
}
451
void* svGetArrElemPtr2(const svOpenArrayHandle h, int indx1, int indx2) {
452
    return _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
453
}
454
void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx3) {
455
    return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
456
}
457

458
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) {
459
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
460
    va_list ap;
461
    va_start(ap, indx1);
462
    switch (varp->udims()) {
463
    case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
464
    case 2: {
465
        const int indx2 = va_arg(ap, int);
466
        _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
467
        break;
468
    }
469
    case 3: {
470
        const int indx2 = va_arg(ap, int);
471
        const int indx3 = va_arg(ap, int);
472
        _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
473
        break;
474
    }
475
    default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break;  // Will error
476
    }
477
    va_end(ap);
478
}
479
void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1) {
480
    _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0);
481
}
482
void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1,
483
                            int indx2) {
484
    _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
485
}
486
void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2,
487
                            int indx3) {
488
    _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
489
}
490
void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) {
491
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
492
    va_list ap;
493
    va_start(ap, indx1);
494
    switch (varp->udims()) {
495
    case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
496
    case 2: {
497
        const int indx2 = va_arg(ap, int);
498
        _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
499
        break;
500
    }
501
    case 3: {
502
        const int indx2 = va_arg(ap, int);
503
        const int indx3 = va_arg(ap, int);
504
        _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
505
        break;
506
    }
507
    default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break;  // Will error
508
    }
509
    va_end(ap);
510
}
511
void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1) {
512
    _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
513
}
514
void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
515
                              int indx2) {
516
    _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
517
}
518
void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
519
                              int indx2, int indx3) {
520
    _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
521
}
522

523
//======================================================================
524
// From simulator storage into user space
525

526
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
527
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
528
    va_list ap;
529
    va_start(ap, indx1);
530
    switch (varp->udims()) {
531
    case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
532
    case 2: {
533
        const int indx2 = va_arg(ap, int);
534
        _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
535
        break;
536
    }
537
    case 3: {
538
        const int indx2 = va_arg(ap, int);
539
        const int indx3 = va_arg(ap, int);
540
        _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
541
        break;
542
    }
543
    default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break;  // Will error
544
    }
545
    va_end(ap);
546
}
547
void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1) {
548
    _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0);
549
}
550
void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
551
    _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
552
}
553
void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
554
                            int indx3) {
555
    _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
556
}
557
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
558
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
559
    va_list ap;
560
    va_start(ap, indx1);
561
    switch (varp->udims()) {
562
    case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
563
    case 2: {
564
        const int indx2 = va_arg(ap, int);
565
        _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
566
        break;
567
    }
568
    case 3: {
569
        const int indx2 = va_arg(ap, int);
570
        const int indx3 = va_arg(ap, int);
571
        _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
572
        break;
573
    }
574
    default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break;  // Will error
575
    }
576
    va_end(ap);
577
}
578
void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1) {
579
    _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
580
}
581
void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
582
    _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
583
}
584
void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
585
                              int indx3) {
586
    _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
587
}
588

589
svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
590
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
591
    svBit out;
592
    va_list ap;
593
    va_start(ap, indx1);
594
    switch (varp->udims()) {
595
    case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
596
    case 2: {
597
        const int indx2 = va_arg(ap, int);
598
        out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
599
        break;
600
    }
601
    case 3: {
602
        const int indx2 = va_arg(ap, int);
603
        const int indx3 = va_arg(ap, int);
604
        out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
605
        break;
606
    }
607
    default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break;  // Will error
608
    }
609
    va_end(ap);
610
    return out;
611
}
612
svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) {
613
    return _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0);
614
}
615
svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
616
    return _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
617
}
618
svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
619
    return _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
620
}
621
svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
622
    // Verilator doesn't support X/Z so can just call Bit version
623
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
624
    svBit out;
625
    va_list ap;
626
    va_start(ap, indx1);
627
    switch (varp->udims()) {
628
    case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
629
    case 2: {
630
        const int indx2 = va_arg(ap, int);
631
        out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
632
        break;
633
    }
634
    case 3: {
635
        const int indx2 = va_arg(ap, int);
636
        const int indx3 = va_arg(ap, int);
637
        out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
638
        break;
639
    }
640
    default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break;  // Will error
641
    }
642
    va_end(ap);
643
    return out;
644
}
645
svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) {
646
    // Verilator doesn't support X/Z so can just call Bit version
647
    return svGetBitArrElem1(s, indx1);
648
}
649
svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
650
    // Verilator doesn't support X/Z so can just call Bit version
651
    return svGetBitArrElem2(s, indx1, indx2);
652
}
653
svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
654
    // Verilator doesn't support X/Z so can just call Bit version
655
    return svGetBitArrElem3(s, indx1, indx2, indx3);
656
}
657

658
void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
659
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
660
    va_list ap;
661
    va_start(ap, indx1);
662
    switch (varp->udims()) {
663
    case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
664
    case 2: {
665
        const int indx2 = va_arg(ap, int);
666
        _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
667
        break;
668
    }
669
    case 3: {
670
        const int indx2 = va_arg(ap, int);
671
        const int indx3 = va_arg(ap, int);
672
        _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
673
        break;
674
    }
675
    default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break;  // Will error
676
    }
677
    va_end(ap);
678
}
679
void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) {
680
    _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0);
681
}
682
void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) {
683
    _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
684
}
685
void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) {
686
    _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
687
}
688
void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) {
689
    // Verilator doesn't support X/Z so can just call Bit version
690
    const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
691
    va_list ap;
692
    va_start(ap, indx1);
693
    switch (varp->udims()) {
694
    case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
695
    case 2: {
696
        const int indx2 = va_arg(ap, int);
697
        _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
698
        break;
699
    }
700
    case 3: {
701
        const int indx2 = va_arg(ap, int);
702
        const int indx3 = va_arg(ap, int);
703
        _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
704
        break;
705
    }
706
    default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break;  // Will error
707
    }
708
    va_end(ap);
709
}
710
void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
711
    // Verilator doesn't support X/Z so can just call Bit version
712
    svPutBitArrElem1(d, value, indx1);
713
}
714
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
715
    // Verilator doesn't support X/Z so can just call Bit version
716
    svPutBitArrElem2(d, value, indx1, indx2);
717
}
718
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2,
719
                        int indx3) {
720
    // Verilator doesn't support X/Z so can just call Bit version
721
    svPutBitArrElem3(d, value, indx1, indx2, indx3);
722
}
723

724
//======================================================================
725
// Functions for working with DPI context
726

727
svScope svGetScope() {
728
    if (VL_UNLIKELY(!Verilated::dpiInContext())) {
729
        VL_SVDPI_CONTEXT_WARN_();
730
        return nullptr;
731
    }
732
    // NOLINTNEXTLINE(google-readability-casting)
733
    return (svScope)(Verilated::dpiScope());
734
}
735

736
svScope svSetScope(const svScope scope) {
737
    const VerilatedScope* const prevScopep = Verilated::dpiScope();
738
    const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
739
    Verilated::dpiScope(vscopep);
740
    // NOLINTNEXTLINE(google-readability-casting)
741
    return (svScope)(prevScopep);
742
}
743

744
const char* svGetNameFromScope(const svScope scope) {
745
    const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
746
    return vscopep->name();
747
}
748

749
svScope svGetScopeFromName(const char* scopeName) {
750
    // NOLINTNEXTLINE(google-readability-casting)
751
    return (svScope)(Verilated::threadContextp()->scopeFind(scopeName));
752
}
753

754
int svPutUserData(const svScope scope, void* userKey, void* userData) {
755
    VerilatedImp::userInsert(scope, userKey, userData);
756
    return 0;
757
}
758

759
void* svGetUserData(const svScope scope, void* userKey) {
760
    return VerilatedImp::userFind(scope, userKey);
761
}
762

763
int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
764
    if (VL_UNLIKELY(!Verilated::dpiInContext())) {
765
        VL_SVDPI_CONTEXT_WARN_();
766
        return false;
767
    }
768
    if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep();  // thread local
769
    if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno();  // thread local
770
    return true;
771
}
772

773
//======================================================================
774
// Time
775

776
int svGetTime(const svScope scope, svTimeVal* time) {
777
    if (VL_UNLIKELY(!time)) return -1;
778
    const QData qtime = VL_TIME_Q();
779
    VlWide<2> itime;
780
    VL_SET_WQ(itime, qtime);
781
    time->low = itime[0];
782
    time->high = itime[1];
783
    return 0;
784
}
785

786
int svGetTimeUnit(const svScope scope, int32_t* time_unit) {
787
    if (VL_UNLIKELY(!time_unit)) return -1;
788
    const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
789
    if (!vscopep) {  // Null asks for global, not unlikely
790
        *time_unit = Verilated::threadContextp()->timeunit();
791
    } else {
792
        *time_unit = vscopep->timeunit();
793
    }
794
    return 0;
795
}
796

797
int svGetTimePrecision(const svScope scope, int32_t* time_precision) {
798
    if (VL_UNLIKELY(!time_precision)) return -1;
799
    *time_precision = Verilated::threadContextp()->timeprecision();
800
    return 0;
801
}
802

803
//======================================================================
804
// Disables
805

806
int svIsDisabledState() {
807
    return 0;  // Disables not implemented
808
}
809

810
void svAckDisabledState() {
811
    // Disables not implemented
812
}
813

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.