// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // // Copyright 2009-2017 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. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //========================================================================= /// /// \file /// \brief Verilator: DPI implementation code /// /// This file must be compiled and linked against all objects /// created from Verilator or called by Verilator that use the DPI. /// /// Code available from: http://www.veripool.org/verilator /// //========================================================================= #define _VERILATED_DPI_CPP_ #include "verilatedos.h" #include "verilated_dpi.h" #include "verilated_imp.h" // On MSVC++ we need svdpi.h to declare exports, not imports #define DPI_PROTOTYPES #undef XXTERN #define XXTERN DPI_EXTERN DPI_DLLESPEC #undef EETERN #define EETERN DPI_EXTERN DPI_DLLESPEC #include "vltstd/svdpi.h" //====================================================================== // Internal macros // Not supported yet #define _VL_SVDPI_UNIMP() \ VL_FATAL_MT(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str()) #define _VL_SVDPI_WARN(message...) \ VL_PRINTF_MT(message) // Function requires a "context" in the import declaration #define _VL_SVDPI_CONTEXT_WARN() \ _VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n"); //====================================================================== //====================================================================== //====================================================================== // DPI ROUTINES const char* svDpiVersion() { return "1800-2005"; } //====================================================================== // Bit-select utility functions. svBit svGetBitselBit(const svBitVecVal* sp, int bit) { return VL_BITRSHIFT_W(sp,bit) & 1; } svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) { // Not VL_BITRSHIFT_W as sp is a different structure type // Verilator doesn't support X/Z so only aval return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1) | (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1)<<1)); } void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(32, bit, dp, s); } void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) { // Verilator doesn't support X/Z so only aval dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1)<>1<>loffset; int upperword = i+word_shift+1; if (upperword <= static_cast(VL_BITWORD_I(msb))) { dp[i] |= sp[upperword] << nbitsfromlow; } } } // Clean result dp[VL_WORDS_I(width)-1] &= VL_MASK_I(width); } void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lsb, int width) { int msb = lsb+width-1; int word_shift = VL_BITWORD_I(lsb); if (VL_BITBIT_I(lsb)==0) { // Just a word extract for (int i=0; i> loffset; dp[i].bval = sp[i+word_shift].bval >> loffset; int upperword = i+word_shift+1; if (upperword <= static_cast(VL_BITWORD_I(msb))) { dp[i].aval |= sp[upperword].aval << nbitsfromlow; dp[i].bval |= sp[upperword].bval << nbitsfromlow; } } } // Clean result dp[VL_WORDS_I(width)-1].aval &= VL_MASK_I(width); dp[VL_WORDS_I(width)-1].bval &= VL_MASK_I(width); } void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width) { // See also _VL_INSERT_WI int hbit = lbit+width-1; int hoffset = VL_BITBIT_I(hbit); int loffset = VL_BITBIT_I(lbit); if (hoffset==VL_SIZEBITS_I && loffset==0) { // Fast and common case, word based insertion dp[VL_BITWORD_I(lbit)] = s; } else { int hword = VL_BITWORD_I(hbit); int lword = VL_BITWORD_I(lbit); if (hword==lword) { // know < 32 bits because above checks it IData insmask = (VL_MASK_I(hoffset-loffset+1))<>nbitsonright) & hinsmask); } } } // cppcheck-suppress passedByValue void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) { int hbit = lbit+width-1; int hoffset = VL_BITBIT_I(hbit); int loffset = VL_BITBIT_I(lbit); if (hoffset==VL_SIZEBITS_I && loffset==0) { // Fast and common case, word based insertion dp[VL_BITWORD_I(lbit)].aval = s.aval; dp[VL_BITWORD_I(lbit)].bval = s.bval; } else { int hword = VL_BITWORD_I(hbit); int lword = VL_BITWORD_I(lbit); if (hword==lword) { // know < 32 bits because above checks it IData insmask = (VL_MASK_I(hoffset-loffset+1))<>nbitsonright) & hinsmask); dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval>>nbitsonright) & hinsmask); } } } //====================================================================== // Open array internals static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) { if (VL_UNLIKELY(!h)) { VL_FATAL_MT(__FILE__,__LINE__,"","%%Error: DPI svOpenArrayHandle function called with NULL handle"); } const VerilatedDpiOpenVar* varp = reinterpret_cast(h); if (VL_UNLIKELY(!varp->magicOk())) { VL_FATAL_MT(__FILE__,__LINE__,"","%%Error: DPI svOpenArrayHandle function called with non-Verilator handle"); } return varp; } //====================================================================== // Open array querying functions int svLeft(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->left(d); } int svRight(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->right(d); } int svLow(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->low(d); } int svHigh(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->high(d); } int svIncrement(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->increment(d); } int svSize(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->elements(d); } int svDimensions(const svOpenArrayHandle h) { return _vl_openhandle_varp(h)->udims(); } /// Return pointer to open array data, or NULL if not in IEEE standard C layout void* svGetArrayPtr(const svOpenArrayHandle h) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h); if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL; return varp->datap(); } /// Return size of open array, or 0 if not in IEEE standard C layout int svSizeOfArray(const svOpenArrayHandle h) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h); if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0; // Truncate 64 bits to int; DPI is limited to 4GB return static_cast(varp->totalSize()); } //====================================================================== // Open array access internals static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, int indx1, int indx2, int indx3) { void* datap = varp->datap(); if (VL_UNLIKELY(nargs != varp->udims())) { _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on %d dimensional array using %d dimensional function.\n", varp->udims(), nargs); return NULL; } if (nargs>=1) { datap = varp->datapAdjustIndex(datap, 1, indx1); if (VL_UNLIKELY(!datap)) { _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 1 out of bounds; %d outside [%d:%d].\n", indx1, varp->left(1), varp->right(1)); return NULL; } } if (nargs>=2) { datap = varp->datapAdjustIndex(datap, 2, indx2); if (VL_UNLIKELY(!datap)) { _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 2 out of bounds; %d outside [%d:%d].\n", indx2, varp->left(2), varp->right(2)); return NULL; } } if (nargs>=3) { datap = varp->datapAdjustIndex(datap, 3, indx3); if (VL_UNLIKELY(!datap)) { _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 3 out of bounds; %d outside [%d:%d].\n", indx1, varp->left(3), varp->right(3)); return NULL; } } return datap; } static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) { if (VL_UNLIKELY(indx < varp->low(0) || indx > varp->high(0))) { _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d outside [%d:%d].\n", indx, varp->left(0), varp->right(0)); return 0; } return indx - varp->low(0); } /// Return pointer to simulator open array element, or NULL if outside range static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h); if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL; void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); return datap; } /// Copy to user bit array from simulator open array static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); if (VL_UNLIKELY(!datap)) return; switch (varp->vltype()) { case VLVT_UINT8: d[0] = *(reinterpret_cast(datap)); return; case VLVT_UINT16: d[0] = *(reinterpret_cast(datap)); return; case VLVT_UINT32: d[0] = *(reinterpret_cast(datap)); return; case VLVT_UINT64: { WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast(datap))); d[0] = lwp[0]; d[1] = lwp[1]; break; } case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); for (int i=0; ipacked().elements()); ++i) d[i] = wdatap[i]; return; } default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return; } } /// Copy to user logic array from simulator open array static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); if (VL_UNLIKELY(!datap)) return; switch (varp->vltype()) { case VLVT_UINT8: d[0].aval = *(reinterpret_cast(datap)); d[0].bval=0; return; case VLVT_UINT16: d[0].aval = *(reinterpret_cast(datap)); d[0].bval=0; return; case VLVT_UINT32: d[0].aval = *(reinterpret_cast(datap)); d[0].bval=0; return; case VLVT_UINT64: { WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast(datap))); d[0].aval = lwp[0]; d[0].bval=0; d[1].aval = lwp[1]; d[0].bval=0; break; } case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); for (int i=0; ipacked().elements()); ++i) { d[i].aval = wdatap[i]; d[i].bval = 0; } return; } default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return; } } /// Copy to simulator open array from from user bit array static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); if (VL_UNLIKELY(!datap)) return; switch (varp->vltype()) { case VLVT_UINT8: *(reinterpret_cast(datap)) = s[0]; return; case VLVT_UINT16: *(reinterpret_cast(datap)) = s[0]; return; case VLVT_UINT32: *(reinterpret_cast(datap)) = s[0]; return; case VLVT_UINT64: *(reinterpret_cast(datap)) = _VL_SET_QII(s[1], s[0]); break; case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); for (int i=0; ipacked().elements()); ++i) wdatap[i] = s[i]; return; } default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return; } } /// Copy to simulator open array from from user logic array static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); if (VL_UNLIKELY(!datap)) return; switch (varp->vltype()) { case VLVT_UINT8: *(reinterpret_cast(datap)) = s[0].aval; return; case VLVT_UINT16: *(reinterpret_cast(datap)) = s[0].aval; return; case VLVT_UINT32: *(reinterpret_cast(datap)) = s[0].aval; return; case VLVT_UINT64: *(reinterpret_cast(datap)) = _VL_SET_QII(s[1].aval, s[0].aval); break; case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); for (int i=0; ipacked().elements()); ++i) wdatap[i] = s[i].aval; return; } default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return; } } /// Return bit from simulator open array static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1, int indx2, int indx3, int indx4) VL_MT_SAFE { // One extra index supported, as need bit number const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); void* datap; int lsb; if (varp->packed().elements()) { datap = _vl_sv_adjusted_datap(varp, nargs-1, indx1, indx2, indx3); lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1 : (nargs==2) ? indx2 : (nargs==3) ? indx3 : indx4)); } else { datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); lsb = 0; } if (VL_UNLIKELY(!datap)) return 0; switch (varp->vltype()) { case VLVT_UINT8: return (*(reinterpret_cast(datap)) >> lsb) & 1; case VLVT_UINT16: return (*(reinterpret_cast(datap)) >> lsb) & 1; case VLVT_UINT32: return (*(reinterpret_cast(datap)) >> lsb) & 1; case VLVT_UINT64: return (*(reinterpret_cast(datap)) >> static_cast(lsb)) & VL_ULL(1); case VLVT_WDATA: { WDataOutP wdatap = (reinterpret_cast(datap)); return VL_BITRSHIFT_W(wdatap, lsb) & 1; } default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return 0; } } /// Update simulator open array from bit static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int nargs, int indx1, int indx2, int indx3, int indx4) VL_MT_SAFE { // One extra index supported, as need bit number value &= 1; // Make sure clean const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); void* datap; int lsb; if (varp->packed().elements()) { datap = _vl_sv_adjusted_datap(varp, nargs-1, indx1, indx2, indx3); lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1 : (nargs==2) ? indx2 : (nargs==3) ? indx3 : indx4)); } else { datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3); lsb = 0; } if (VL_UNLIKELY(!datap)) return; switch (varp->vltype()) { case VLVT_UINT8: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast(datap)), value); return; case VLVT_UINT16: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast(datap)), value); return; case VLVT_UINT32: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast(datap)), value); return; case VLVT_UINT64: VL_ASSIGNBIT_QI(-1, lsb, *(reinterpret_cast(datap)), value); return; case VLVT_WDATA: VL_ASSIGNBIT_WI(-1, lsb, (reinterpret_cast(datap)), value); return; default: _VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype()); return; } } //====================================================================== // DPI accessors that simply call above functions void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h); void* datap; va_list ap; va_start(ap, indx1); // va_arg is a macro, so need temporaries as used below switch (varp->udims()) { case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break; case 2: { int indx2=va_arg(ap,int); datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3); break; } default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break; // Will error } va_end(ap); return datap; } void* svGetArrElemPtr1(const svOpenArrayHandle h, int indx1) { return _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); } void* svGetArrElemPtr2(const svOpenArrayHandle h, int indx1, int indx2) { return _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0); } void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx3) { return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3); } void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; } default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error } va_end(ap); } void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1) { _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); } void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2) { _vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0); } void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2, int indx3) { _vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); } void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; } default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error } va_end(ap); } void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1) { _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); } void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2) { _vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); } void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, int indx2, int indx3) { _vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); } //====================================================================== // From simulator storage into user space void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; } default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error } va_end(ap); } void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1) { _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); } void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) { _vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0); } void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); } void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; } default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error } va_end(ap); } void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1) { _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); } void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) { _vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); } void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2, int indx3) { _vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); } svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); svBit out; va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break; case 2: { int indx2=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; } case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; } default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error } va_end(ap); return out; } svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) { return _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); } svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) { return _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); } svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) { return _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); } svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) { // Verilator doesn't support X/Z so can just call Bit version const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s); svBit out; va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break; case 2: { int indx2=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; } case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int); out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; } default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error } va_end(ap); return out; } svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) { // Verilator doesn't support X/Z so can just call Bit version return svGetBitArrElem1(s, indx1); } svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) { // Verilator doesn't support X/Z so can just call Bit version return svGetBitArrElem2(s, indx1, indx2); } svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) { // Verilator doesn't support X/Z so can just call Bit version return svGetBitArrElem3(s, indx1, indx2, indx3); } void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) { const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; } case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; } default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error } va_end(ap); } void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) { _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); } void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) { _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); } void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) { _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); } void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) { // Verilator doesn't support X/Z so can just call Bit version const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d); va_list ap; va_start(ap, indx1); switch (varp->udims()) { case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break; case 2: { int indx2=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; } case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; } case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int); _vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; } default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error } va_end(ap); } void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) { // Verilator doesn't support X/Z so can just call Bit version svPutBitArrElem1(d, value, indx1); } void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) { // Verilator doesn't support X/Z so can just call Bit version svPutBitArrElem2(d, value, indx1, indx2); } void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) { // Verilator doesn't support X/Z so can just call Bit version svPutBitArrElem3(d, value, indx1, indx2, indx3); } //====================================================================== // Functions for working with DPI context svScope svGetScope() { if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return NULL; } return (svScope)Verilated::dpiScope(); } svScope svSetScope(const svScope scope) { const VerilatedScope* prevScopep = Verilated::dpiScope(); const VerilatedScope* vscopep = reinterpret_cast(scope); Verilated::dpiScope(vscopep); return (svScope)prevScopep; } const char* svGetNameFromScope(const svScope scope) { const VerilatedScope* vscopep = reinterpret_cast(scope); return vscopep->name(); } svScope svGetScopeFromName(const char* scopeName) { return (svScope)VerilatedImp::scopeFind(scopeName); } int svPutUserData(const svScope scope, void* userKey, void* userData) { VerilatedImp::userInsert(scope,userKey,userData); return 0; } void* svGetUserData(const svScope scope, void* userKey) { return VerilatedImp::userFind(scope,userKey); } int svGetCallerInfo(const char** fileNamepp, int *lineNumberp) { if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return false; } if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep(); // thread local if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno(); // thread local return true; } //====================================================================== // Disables int svIsDisabledState() { return 0; // Disables not implemented } void svAckDisabledState() { // Disables not implemented }