From 0102efd4eaede5e4baa490a17c63a7b94cdaa7ee Mon Sep 17 00:00:00 2001 From: Yutetsu TAKATSUKASA Date: Thu, 19 Nov 2020 22:02:58 +0900 Subject: [PATCH] Support unpacked array in DPI-C (#2648) * Add tests for unpacked array in DPI-C * Add more generic parameter generator to AstNodes * Supports multi dimensional array in DPI ( DPI argmuments <=> Verilator internal type conversion) consider typedef in V3Task fix export test fix inout for scalar support export func of time * V3Premit does not show an error for wide words nor ArraySel * Unnecessary pack func for unapcked array does not appear anymore * Support unpacked array in runtime header - Add an overload for lvalue VL_CVT_PACK_STR_NN - Allow conversion from void * * touch up tests for codacy advices * resolve free functions. no functional change intended. --- src/V3AstNodes.cpp | 135 +- src/V3AstNodes.h | 3 + src/V3Premit.cpp | 4 +- src/V3ProtectLib.cpp | 7 +- src/V3Task.cpp | 161 ++- src/V3Task.h | 3 +- src/V3Width.cpp | 42 + test_regress/t/t_dpi_arg_inout_unpack.cpp | 860 ++++++++++++ test_regress/t/t_dpi_arg_inout_unpack.pl | 44 + test_regress/t/t_dpi_arg_inout_unpack.v | 1162 +++++++++++++++++ .../t/t_dpi_arg_inout_unpack__Dpi.out | 313 +++++ test_regress/t/t_dpi_arg_input_unpack.cpp | 778 +++++++++++ test_regress/t/t_dpi_arg_input_unpack.pl | 44 + test_regress/t/t_dpi_arg_input_unpack.v | 770 +++++++++++ .../t/t_dpi_arg_input_unpack__Dpi.out | 313 +++++ test_regress/t/t_dpi_arg_output_unpack.cpp | 655 ++++++++++ test_regress/t/t_dpi_arg_output_unpack.pl | 44 + test_regress/t/t_dpi_arg_output_unpack.v | 761 +++++++++++ .../t/t_dpi_arg_output_unpack__Dpi.out | 313 +++++ test_regress/t/t_dpi_unpack_bad.out | 30 + test_regress/t/t_dpi_unpack_bad.pl | 19 + test_regress/t/t_dpi_unpack_bad.v | 31 + 22 files changed, 6421 insertions(+), 71 deletions(-) create mode 100644 test_regress/t/t_dpi_arg_inout_unpack.cpp create mode 100755 test_regress/t/t_dpi_arg_inout_unpack.pl create mode 100644 test_regress/t/t_dpi_arg_inout_unpack.v create mode 100644 test_regress/t/t_dpi_arg_inout_unpack__Dpi.out create mode 100644 test_regress/t/t_dpi_arg_input_unpack.cpp create mode 100755 test_regress/t/t_dpi_arg_input_unpack.pl create mode 100644 test_regress/t/t_dpi_arg_input_unpack.v create mode 100644 test_regress/t/t_dpi_arg_input_unpack__Dpi.out create mode 100644 test_regress/t/t_dpi_arg_output_unpack.cpp create mode 100755 test_regress/t/t_dpi_arg_output_unpack.pl create mode 100644 test_regress/t/t_dpi_arg_output_unpack.v create mode 100644 test_regress/t/t_dpi_arg_output_unpack__Dpi.out create mode 100644 test_regress/t/t_dpi_unpack_bad.out create mode 100755 test_regress/t/t_dpi_unpack_bad.pl create mode 100644 test_regress/t/t_dpi_unpack_bad.v diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 3f5dfb2d9..11bc1dd17 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -455,38 +455,99 @@ string AstVar::cPubArgType(bool named, bool forReturn) const { return arg; } -string AstVar::dpiArgType(bool named, bool forReturn) const { - if (forReturn) named = false; - string arg; - if (isDpiOpenArray()) { - arg = "const svOpenArrayHandle"; - } else if (!basicp()) { - arg = "UNKNOWN"; - } else if (basicp()->isDpiBitVec()) { - if (forReturn) { - arg = "svBitVecVal"; - } else if (isReadOnly()) { - arg = "const svBitVecVal*"; - } else { - arg = "svBitVecVal*"; - } - } else if (basicp()->isDpiLogicVec()) { - if (forReturn) { - arg = "svLogicVecVal"; - } else if (isReadOnly()) { - arg = "const svLogicVecVal*"; - } else { - arg = "svLogicVecVal*"; - } - } else { - arg = basicp()->keyword().dpiType(); - if (basicp()->keyword().isDpiUnsignable() && !basicp()->isSigned()) { - arg = "unsigned " + arg; - } - if (!forReturn && isWritable()) arg += "*"; +class dpiTypesToStringConverter { +public: + virtual string openArray(const AstVar*) const { return "const svOpenArrayHandle"; } + virtual string bitLogicVector(const AstVar* varp, bool isBit) const { + return isBit ? "svBitVecVal" : "svLogicVecVal"; } - if (named) arg += " " + name(); - return arg; + virtual string primitive(const AstVar* varp) const { + string type; + if (varp->basicp()->keyword().isDpiUnsignable() && !varp->basicp()->isSigned()) { + type = "unsigned "; + } + type += varp->basicp()->keyword().dpiType(); + return type; + } + string convert(const AstVar* varp) const { + if (varp->isDpiOpenArray()) { + return openArray(varp); + } else if (!varp->basicp()) { + return "UNKNOWN"; + } else if (varp->basicp()->isDpiBitVec() || varp->basicp()->isDpiLogicVec()) { + return bitLogicVector(varp, varp->basicp()->isDpiBitVec()); + } else { + return primitive(varp); + } + } +}; + +string AstVar::dpiArgType(bool named, bool forReturn) const { + if (forReturn) { + return dpiTypesToStringConverter{}.convert(this); + } else { + class converter : public dpiTypesToStringConverter { + virtual string bitLogicVector(const AstVar* varp, bool isBit) const override { + return string(varp->isReadOnly() ? "const " : "") + + dpiTypesToStringConverter::bitLogicVector(varp, isBit) + '*'; + } + virtual string primitive(const AstVar* varp) const override { + string type = dpiTypesToStringConverter::primitive(varp); + if (varp->isWritable() || VN_IS(varp->dtypep()->skipRefp(), UnpackArrayDType)) { + if (!varp->isWritable() + && varp->basicp()->keyword() != AstBasicDTypeKwd::STRING) + type = "const " + type; + type += "*"; + } + return type; + } + }; + string arg = converter{}.convert(this); + if (named) arg += " " + name(); + return arg; + } +} + +string AstVar::dpiTmpVarType(const string& varName) const { + class converter : public dpiTypesToStringConverter { + string m_name; + string arraySuffix(const AstVar* varp, size_t n) const { + if (AstUnpackArrayDType* unpackp + = VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) { + // Convert multi dimensional unpacked array to 1D array + if (n == 0) n = 1; + n *= unpackp->arrayUnpackedElements(); + return '[' + cvtToStr(n) + ']'; + } else if (n > 0) { + return '[' + cvtToStr(n) + ']'; + } else { + return ""; + } + } + virtual string openArray(const AstVar* varp) const override { + return dpiTypesToStringConverter::openArray(varp) + ' ' + m_name + + arraySuffix(varp, 0); + } + virtual string bitLogicVector(const AstVar* varp, bool isBit) const override { + string type = dpiTypesToStringConverter::bitLogicVector(varp, isBit); + type += ' ' + m_name + arraySuffix(varp, varp->widthWords()); + return type; + } + virtual string primitive(const AstVar* varp) const override { + string type = dpiTypesToStringConverter::primitive(varp); + if (varp->isWritable() || VN_IS(varp->dtypep()->skipRefp(), UnpackArrayDType)) { + if (!varp->isWritable() && varp->basicp()->keyword() == AstBasicDTypeKwd::CHANDLE) + type = "const " + type; + } + type += ' ' + m_name + arraySuffix(varp, 0); + return type; + } + + public: + explicit converter(const string& name) + : m_name(name) {} + }; + return converter{varName}.convert(this); } string AstVar::scType() const { @@ -1347,6 +1408,18 @@ string AstUnpackArrayDType::prettyDTypeName() const { os << subp->prettyDTypeName() << "$" << ranges; return os.str(); } +std::vector AstUnpackArrayDType::unpackDimensions() { + std::vector dims; + for (AstUnpackArrayDType* unpackp = this; unpackp;) { + dims.push_back(unpackp); + if (AstNodeDType* subp = unpackp->subDTypep()) { + unpackp = VN_CAST(subp, UnpackArrayDType); + } else { + unpackp = nullptr; + } + } + return dims; +} void AstNetlist::dump(std::ostream& str) const { this->AstNode::dump(str); str << " [" << timeunit() << "/" << timeprecision() << "]"; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index c70763cc9..d38a39675 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -721,6 +721,8 @@ public: } ASTNODE_NODE_FUNCS(UnpackArrayDType) virtual string prettyDTypeName() const override; + // Outer dimension comes first. The first element is this node. + std::vector unpackDimensions(); }; class AstUnsizedArrayDType final : public AstNodeDType { @@ -2026,6 +2028,7 @@ public: // Return C /*public*/ type for argument: bool, uint32_t, uint64_t, etc. string cPubArgType(bool named, bool forReturn) const; string dpiArgType(bool named, bool forReturn) const; // Return DPI-C type for argument + string dpiTmpVarType(const string& varName) const; // Return Verilator internal type for argument: CData, SData, IData, WData string vlArgType(bool named, bool forReturn, bool forFunc, const string& namespc = "") const; string vlEnumType() const; // Return VerilatorVarType: VLVT_UINT32, etc diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 5865a902f..ac5582b4c 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -127,7 +127,9 @@ private: } else if (VN_IS(nodep->backp(), Sel) && VN_CAST(nodep->backp(), Sel)->widthp() == nodep) { // AstSel::width must remain a constant - } else if (nodep->firstAbovep() && VN_IS(nodep->firstAbovep(), ArraySel)) { + } else if ((nodep->firstAbovep() && VN_IS(nodep->firstAbovep(), ArraySel)) + || ((VN_IS(m_stmtp, CCall) || VN_IS(m_stmtp, CStmt)) + && VN_IS(nodep, ArraySel))) { // ArraySel's are pointer refs, ignore } else { UINFO(4, "Cre Temp: " << nodep << endl); diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 599699b5a..188a5e8f3 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -411,11 +411,12 @@ private: string cInputConnection(AstVar* varp) { string frstmt; - bool useSetWSvlv = V3Task::dpiToInternalFrStmt(varp, varp->name(), frstmt); + string ket; + bool useSetWSvlv = V3Task::dpiToInternalFrStmt(varp, varp->name(), frstmt, ket); if (useSetWSvlv) { - return frstmt + " handlep__V->" + varp->name() + ", " + varp->name() + ");\n"; + return frstmt + ket + " handlep__V->" + varp->name() + ", " + varp->name() + ");\n"; } - return "handlep__V->" + varp->name() + " = " + frstmt + ";\n"; + return "handlep__V->" + varp->name() + " = " + frstmt + ket + ";\n"; } void handleClock(AstVar* varp) { diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 90f776cf3..11829195d 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -641,11 +641,7 @@ private: } AstNode* createDpiTemp(AstVar* portp, const string& suffix) { - string stmt = portp->dpiArgType(false, true) + " " + portp->name() + suffix; - if (!portp->basicp()->isDpiPrimitive()) { - stmt += "[" + cvtToStr(portp->widthWords()) + "]"; - } - stmt += ";\n"; + const string stmt = portp->dpiTmpVarType(portp->name() + suffix) + ";\n"; return new AstCStmt(portp->fileline(), stmt); } @@ -655,30 +651,80 @@ private: return new AstCStmt(portp->fileline(), stmt); } + static std::vector> unpackDimsAndStrides(AstVar* varp) { + std::vector> dimStrides; + if (AstUnpackArrayDType* dtypep = VN_CAST(varp->dtypep()->skipRefp(), UnpackArrayDType)) { + const std::vector dims = dtypep->unpackDimensions(); + dimStrides.resize(dims.size(), {nullptr, 0}); + dimStrides.back() = {dims.back(), 1}; + for (ssize_t i = dims.size() - 2; i >= 0; --i) { + dimStrides[i].first = dims[i]; + dimStrides[i].second = dimStrides[i + 1].second * dims[i + 1]->elementsConst(); + } + } + return dimStrides; + } + AstNode* createAssignDpiToInternal(AstVarScope* portvscp, const string& frName) { // Create assignment from DPI temporary into internal format + // DPI temporary is scalar or 1D array (if unpacked array) + // Internal representation is scalar, 1D, or multi-dimensional array (similar to SV) AstVar* portp = portvscp->varp(); string frstmt; - bool useSetWSvlv = V3Task::dpiToInternalFrStmt(portp, frName, frstmt); - if (useSetWSvlv) { - AstNode* linesp = new AstText(portp->fileline(), frstmt); - linesp->addNext(new AstVarRef(portp->fileline(), portvscp, VAccess::WRITE)); - linesp->addNext(new AstText(portp->fileline(), "," + frName + ");")); - return new AstCStmt(portp->fileline(), linesp); - } + string ket; + const bool useSetWSvlv = V3Task::dpiToInternalFrStmt(portp, frName, frstmt, ket); // Use a AstCMath, as we want V3Clean to mask off bits that don't make sense. int cwidth = VL_IDATASIZE; - if (portp->basicp()) { + if (!useSetWSvlv && portp->basicp()) { if (portp->basicp()->keyword().isBitLogic()) { cwidth = VL_EDATASIZE * portp->widthWords(); } else { cwidth = portp->basicp()->keyword().width(); } } - AstNode* newp = new AstAssign( - portp->fileline(), new AstVarRef(portp->fileline(), portvscp, VAccess::WRITE), - new AstSel(portp->fileline(), new AstCMath(portp->fileline(), frstmt, cwidth, false), - 0, portp->width())); + + const std::vector> dimStrides + = unpackDimsAndStrides(portvscp->varp()); + const int total = dimStrides.empty() ? 1 + : dimStrides.front().first->elementsConst() + * dimStrides.front().second; + AstNode* newp = nullptr; + const int widthWords = portvscp->varp()->basicp()->widthWords(); + for (int i = 0; i < total; ++i) { + AstNode* srcp = new AstVarRef(portvscp->fileline(), portvscp, VAccess::WRITE); + // extract a scalar from multi-dimensional array (internal format) + for (auto&& dimStride : dimStrides) { + const size_t dimIdx = (i / dimStride.second) % dimStride.first->elementsConst(); + srcp = new AstArraySel(portvscp->fileline(), srcp, dimIdx); + } + AstNode* stmtp = nullptr; + // extract a scalar from DPI temporary var that is scalar or 1D array + if (useSetWSvlv) { + AstNode* linesp = new AstText(portvscp->fileline(), frstmt + ket); + linesp->addNext(srcp); + linesp->addNext( + new AstText(portvscp->fileline(), + "," + frName + " + " + cvtToStr(i * widthWords) + ");\n")); + stmtp = new AstCStmt(portvscp->fileline(), linesp); + } else { + string from = frstmt; + if (!dimStrides.empty()) { + // e.g. time is 64bit svLogicVector + const int coef = portvscp->varp()->basicp()->isDpiLogicVec() ? widthWords : 1; + from += "[" + cvtToStr(i * coef) + "]"; + } + from += ket; + AstNode* rhsp = new AstSel(portp->fileline(), + new AstCMath(portp->fileline(), from, cwidth, false), 0, + portp->width()); + stmtp = new AstAssign(portp->fileline(), srcp, rhsp); + } + if (i > 0) { + newp->addNext(stmtp); + } else { + newp = stmtp; + } + } return newp; } @@ -749,7 +795,10 @@ private: if (portp->isNonOutput()) { std::string frName - = portp->isInoutish() && portp->basicp()->isDpiPrimitive() ? "*" : ""; + = portp->isInoutish() && portp->basicp()->isDpiPrimitive() + && portp->dtypep()->skipRefp()->arrayUnpackedElements() == 1 + ? "*" + : ""; frName += portp->name(); dpip->addStmtsp(createAssignDpiToInternal(outvscp, frName)); } @@ -913,7 +962,7 @@ private: args += "&" + name; } else { if (portp->isWritable() && portp->basicp()->isDpiPrimitive()) { - args += "&"; + if (!VN_IS(portp->dtypep()->skipRefp(), UnpackArrayDType)) args += "&"; } args += portp->name() + tmpSuffixp; @@ -1532,37 +1581,76 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp) string V3Task::assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix, const string& frPrefix) { // Create assignment from internal format into DPI temporary + // Internal representation is scalar, 1D, or multi-dimensional array (similar to SV) + // DPI temporary is scalar or 1D array (if unpacked array) string stmt; string ket; // Someday we'll have better type support, and this can make variables and casts. // But for now, we'll just text-bash it. string frName = frPrefix + portp->name() + frSuffix; string toName = portp->name() + toSuffix; - if (portp->basicp()->isDpiBitVec()) { - stmt += ("VL_SET_SVBV_" + string(portp->dtypep()->charIQWN()) + "(" - + cvtToStr(portp->width()) + ", " + toName + ", " + frName + ")"); - } else if (portp->basicp()->isDpiLogicVec()) { - stmt += ("VL_SET_SVLV_" + string(portp->dtypep()->charIQWN()) + "(" - + cvtToStr(portp->width()) + ", " + toName + ", " + frName + ")"); + size_t unpackSize = 1; // non-unpacked array is treated as size 1 + int unpackDim = 0; + if (AstUnpackArrayDType* unpackp = VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) { + unpackSize = unpackp->arrayUnpackedElements(); + unpackDim = unpackp->dimensions(false).second; + if (unpackDim > 0) UASSERT_OBJ(unpackSize > 0, portp, "size must be greater than 0"); + } + if (portp->basicp()->isDpiBitVec() || portp->basicp()->isDpiLogicVec()) { + const bool isBit = portp->basicp()->isDpiBitVec(); + const string idx = portp->name() + "__Vidx"; + stmt = "for (size_t " + idx + " = 0; " + idx + " < " + cvtToStr(unpackSize) + "; ++" + idx + + ") "; + stmt += (isBit ? "VL_SET_SVBV_" : "VL_SET_SVLV_") + + string(portp->dtypep()->skipRefp()->charIQWN()) + "(" + cvtToStr(portp->width()) + + ", "; + stmt += toName + " + " + cvtToStr(portp->dtypep()->skipRefp()->widthWords()) + " * " + idx + + ", "; + if (unpackDim > 0) { // Access multi-dimensional array as a 1D array + stmt += "(&" + frName; + for (int i = 0; i < unpackDim; ++i) stmt += "[0]"; + stmt += ")[" + idx + "])"; + } else { + stmt += frName + ")"; + } } else { - if (isPtr) stmt += "*"; // DPI outputs are pointers - stmt += toName + " = "; - if (portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::CHANDLE) { + const bool isChandle + = portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::CHANDLE; + const bool isString + = portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::STRING; + const string idx = portp->name() + "__Vidx"; + stmt = "for (size_t " + idx + " = 0; " + idx + " < " + cvtToStr(unpackSize) + "; ++" + idx + + ") "; + if (unpackDim > 0) { + stmt += toName + "[" + idx + "]"; + } else { + if (isPtr) stmt += "*"; // DPI outputs are pointers + stmt += toName; + } + stmt += " = "; + if (isChandle) { stmt += "VL_CVT_Q_VP("; ket += ")"; } - stmt += frName; - if (portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::STRING) { - stmt += ".c_str()"; + if (unpackDim > 0) { + stmt += "(&" + frName; + for (int i = 0; i < unpackDim; ++i) stmt += "[0]"; + stmt += ")[" + idx + "]"; + } else { + stmt += frName; } + if (isString) stmt += ".c_str()"; } stmt += ket + ";\n"; return stmt; } -bool V3Task::dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt) { +bool V3Task::dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt, + string& ket) { + ket.clear(); if (portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::CHANDLE) { - frstmt = "VL_CVT_VP_Q(" + frName + ")"; + frstmt = "VL_CVT_VP_Q(" + frName; + ket = ")"; } else if ((portp->basicp() && portp->basicp()->isDpiPrimitive())) { frstmt = frName; } else { @@ -1572,8 +1660,11 @@ bool V3Task::dpiToInternalFrStmt(AstVar* portp, const string& frName, string& fr frstmt = "VL_SET_W_" + frSvType + "(" + cvtToStr(portp->width()) + ","; return true; } else { - frstmt = "VL_SET_" + string(portp->dtypep()->charIQWN()) + "_" + frSvType + "(" - + frName + ")"; + const AstNodeDType* dtypep = portp->dtypep()->skipRefp(); + frstmt = "VL_SET_" + string(dtypep->charIQWN()) + "_" + frSvType + "("; + if (VN_IS(dtypep, UnpackArrayDType)) frstmt += "&"; + frstmt += frName; + ket = ")"; } } return false; diff --git a/src/V3Task.h b/src/V3Task.h index 9c162dccc..78d7b0dde 100644 --- a/src/V3Task.h +++ b/src/V3Task.h @@ -39,7 +39,8 @@ public: static V3TaskConnects taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp); static string assignInternalToDpi(AstVar* portp, bool isPtr, const string& frSuffix, const string& toSuffix, const string& frPrefix = ""); - static bool dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt); + static bool dpiToInternalFrStmt(AstVar* portp, const string& frName, string& frstmt, + string& ket); static const char* dpiTemporaryVarSuffix(); }; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index ed88444a9..556a0cc9c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -4238,6 +4238,46 @@ private: nodep->dtypeFrom(nodep->taskp()); // if (debug()) nodep->dumpTree(cout, " FuncOut: "); } + // Returns true if dtypep0 and dtypep1 have same dimensions + static bool areSameSize(AstUnpackArrayDType* dtypep0, AstUnpackArrayDType* dtypep1) { + const std::vector dims0 = dtypep0->unpackDimensions(); + const std::vector dims1 = dtypep1->unpackDimensions(); + if (dims0.size() != dims1.size()) return false; + for (size_t i = 0; i < dims0.size(); ++i) { + if (dims0[i]->elementsConst() != dims1[i]->elementsConst()) return false; + } + return true; + } + // Makes sure that port and pin have same size and same datatype + void checkUnpackedArrayArgs(AstVar* portp, AstNode* pinp) { + if (AstUnpackArrayDType* portDtypep + = VN_CAST(portp->dtypep()->skipRefp(), UnpackArrayDType)) { + if (AstUnpackArrayDType* pinDtypep + = VN_CAST(pinp->dtypep()->skipRefp(), UnpackArrayDType)) { + if (!areSameSize(portDtypep, pinDtypep)) { + pinp->v3warn(E_UNSUPPORTED, + "Shape of the argument does not match the shape of the parameter " + << "(" << pinDtypep->prettyDTypeNameQ() << " v.s. " + << portDtypep->prettyDTypeNameQ() << ")"); + } + if (portDtypep->basicp()->width() != pinDtypep->basicp()->width() + || (portDtypep->basicp()->keyword() != pinDtypep->basicp()->keyword() + && !(portDtypep->basicp()->keyword() == AstBasicDTypeKwd::LOGIC_IMPLICIT + && pinDtypep->basicp()->keyword() == AstBasicDTypeKwd::LOGIC) + && !(portDtypep->basicp()->keyword() == AstBasicDTypeKwd::LOGIC + && pinDtypep->basicp()->keyword() + == AstBasicDTypeKwd::LOGIC_IMPLICIT))) { + pinp->v3warn(E_UNSUPPORTED, + "Shape of the argument does not match the shape of the parameter " + << "(" << pinDtypep->basicp()->prettyDTypeNameQ() << " v.s. " + << portDtypep->basicp()->prettyDTypeNameQ() << ")"); + } + } else { + pinp->v3warn(E_UNSUPPORTED, "Argument is not an unpacked array while parameter " + << portp->prettyNameQ() << " is"); + } + } + } void processFTaskRefArgs(AstNodeFTaskRef* nodep) { // For arguments, is assignment-like context; see IEEE rules in AstNodeAssign // Function hasn't been widthed, so make it so. @@ -4288,6 +4328,7 @@ private: else if (portp->basicp() && portp->basicp()->keyword() == AstBasicDTypeKwd::STRING && !VN_IS(pinp, CvtPackString) && !VN_IS(pinp, SFormatF) // Already generates a string + && !VN_IS(portp->dtypep(), UnpackArrayDType) // Unpacked array must match && !(VN_IS(pinp, VarRef) && VN_CAST(pinp, VarRef)->varp()->basicp()->keyword() == AstBasicDTypeKwd::STRING)) { @@ -4311,6 +4352,7 @@ private: AstNode* pinp = argp->exprp(); if (!pinp) continue; // Argument error we'll find later // Change data types based on above accept completion + if (nodep->taskp()->dpiImport()) checkUnpackedArrayArgs(portp, pinp); if (portp->isDouble()) VL_DO_DANGLING(spliceCvtD(pinp), pinp); } } diff --git a/test_regress/t/t_dpi_arg_inout_unpack.cpp b/test_regress/t/t_dpi_arg_inout_unpack.cpp new file mode 100644 index 000000000..9b029bfbd --- /dev/null +++ b/test_regress/t/t_dpi_arg_inout_unpack.cpp @@ -0,0 +1,860 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include +#include +#include +#include +#include + +// clang-format off +#if defined(NCSC) +// Used by NC's svdpi.h to pick up svLogicVecVal with _.aval and _.bval fields, +// rather than the IEEE 1800-2005 version which has _.a and _.b fields. +# define DPI_COMPATIBILITY_VERSION_1800v2012 +#endif + +#include "svdpi.h" + +#if defined(VERILATOR) // Verilator +# include "Vt_dpi_arg_inout_unpack__Dpi.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_SHORTREAL +# define NO_UNPACK_STRUCT +# define CONSTARG const +#elif defined(VCS) // VCS +# include "../vc_hdrs.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_TIME +# define CONSTARG const +#elif defined(NCSC) // NC +# include "dpi-exp.h" +# include "dpi-imp.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_TIME +# define NO_INTEGER +# define NO_SHORTREAL +// Sadly NC does not declare pass-by reference input arguments as const +# define CONSTARG +#elif defined(MS) // ModelSim +# include "dpi.h" +typedef int64_t sv_longint_t; +typedef uint64_t sv_longint_unsigned_t; +# define CONSTARG const +#else +# error "Unknown simulator for DPI test" +#endif +// clang-format on + +//====================================================================== +// Implementations of imported functions +//====================================================================== + +namespace { // unnamed namespace + +const bool VERBOSE_MESSAGE = false; + +#define stop() \ + do { \ + printf(__FILE__ ":%d Bad value\n", __LINE__); \ + abort(); \ + } while (0) + +void set_uint(svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselLogic(v0, i, (val >> i) & 1); + else + svPutBitselLogic(v0, i, 0); + } +} + +void set_uint(svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselBit(v0, i, (val >> i) & 1); + else + svPutBitselBit(v0, i, 0); + } +} + +template bool compare(const T& act, const T& exp) { + if (exp == act) { + if (VERBOSE_MESSAGE) { std::cout << "OK Exp:" << exp << " actual:" << act << std::endl; } + return true; + } else { + std::cout << "NG Exp:" << exp << " actual:" << act << std::endl; + return false; + } +} + +bool compare(const svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselLogic(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +bool compare(const svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselBit(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +template bool update_0d(T* v) { + if (!compare(*v, 42)) return false; + ++(*v); + return true; +} + +template bool update_1d(T* v) { + if (!compare(v[0], 43)) return false; + if (!compare(v[1], 44)) return false; + ++v[0]; + ++v[1]; + return true; +} + +template bool update_2d(T* v) { + if (!compare(v[0 * 2 + 1], 45)) return false; + if (!compare(v[1 * 2 + 1], 46)) return false; + if (!compare(v[2 * 2 + 1], 47)) return false; + ++v[0 * 2 + 1]; + ++v[1 * 2 + 1]; + ++v[2 * 2 + 1]; + return true; +} + +template bool update_3d(T* v) { + if (!compare(v[(0 * 3 + 0) * 2 + 0], 48)) return false; + if (!compare(v[(1 * 3 + 0) * 2 + 0], 49)) return false; + if (!compare(v[(2 * 3 + 0) * 2 + 0], 50)) return false; + if (!compare(v[(3 * 3 + 0) * 2 + 0], 51)) return false; + ++v[(0 * 3 + 0) * 2 + 0]; + ++v[(1 * 3 + 0) * 2 + 0]; + ++v[(2 * 3 + 0) * 2 + 0]; + ++v[(3 * 3 + 0) * 2 + 0]; + return true; +} + +template bool update_0d(T* v, int bitwidth) { + if (!compare(v, 42, bitwidth)) return false; + set_uint(v, 43, bitwidth); + return true; +} +template bool update_1d(T* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + if (!compare(v + unit * 0, 43, bitwidth)) return false; + if (!compare(v + unit * 1, 44, bitwidth)) return false; + set_uint(v + unit * 0, 44, bitwidth); + set_uint(v + unit * 1, 45, bitwidth); + return true; +} +template bool update_2d(T* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + if (!compare(v + unit * (0 * 2 + 1), 45, bitwidth)) return false; + if (!compare(v + unit * (1 * 2 + 1), 46, bitwidth)) return false; + if (!compare(v + unit * (2 * 2 + 1), 47, bitwidth)) return false; + set_uint(v + unit * (0 * 2 + 1), 46, bitwidth); + set_uint(v + unit * (1 * 2 + 1), 47, bitwidth); + set_uint(v + unit * (2 * 2 + 1), 48, bitwidth); + return true; +} +template bool update_3d(T* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + if (!compare(v + unit * ((0 * 3 + 0) * 2 + 0), 48, bitwidth)) return false; + if (!compare(v + unit * ((1 * 3 + 0) * 2 + 0), 49, bitwidth)) return false; + if (!compare(v + unit * ((2 * 3 + 0) * 2 + 0), 50, bitwidth)) return false; + if (!compare(v + unit * ((3 * 3 + 0) * 2 + 0), 51, bitwidth)) return false; + set_uint(v + unit * ((0 * 3 + 0) * 2 + 0), 49, bitwidth); + set_uint(v + unit * ((1 * 3 + 0) * 2 + 0), 50, bitwidth); + set_uint(v + unit * ((2 * 3 + 0) * 2 + 0), 51, bitwidth); + set_uint(v + unit * ((3 * 3 + 0) * 2 + 0), 52, bitwidth); + return true; +} + +template void set_values(T (&v)[4][3][2]) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) v[i][j][k] = 0; + v[3][2][1] = 42; + v[2][1][0] = 43; + v[2][1][1] = 44; + v[1][0][1] = 45; + v[1][1][1] = 46; + v[1][2][1] = 47; + v[0][0][0] = 48; + v[1][0][0] = 49; + v[2][0][0] = 50; + v[3][0][0] = 51; +} + +template void set_values(T (&v)[4][3][2][N], int bitwidth) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) set_uint(v[i][j][k], 0, bitwidth); + set_uint(v[3][2][1], 42, bitwidth); + set_uint(v[2][1][0], 43, bitwidth); + set_uint(v[2][1][1], 44, bitwidth); + set_uint(v[1][0][1], 45, bitwidth); + set_uint(v[1][1][1], 46, bitwidth); + set_uint(v[1][2][1], 47, bitwidth); + set_uint(v[0][0][0], 48, bitwidth); + set_uint(v[1][0][0], 49, bitwidth); + set_uint(v[2][0][0], 50, bitwidth); + set_uint(v[3][0][0], 51, bitwidth); +} + +template bool check_0d(T v) { return compare(v, 43); } +template bool check_1d(const T (&v)[2]) { + return compare(v[0], 44) && compare(v[1], 45); +} +template bool check_2d(const T (&v)[3][2]) { + return compare(v[0][1], 46) && compare(v[1][1], 47) && compare(v[2][1], 48); +} +template bool check_3d(const T (&v)[4][3][2]) { + return compare(v[0][0][0], 49) && compare(v[1][0][0], 50) && compare(v[2][0][0], 51) + && compare(v[3][0][0], 52); +} + +template bool check_0d(const T (&v)[N], unsigned int bitwidth) { + return compare(v, 43, bitwidth); +} +template bool check_1d(const T (&v)[2][N], unsigned int bitwidth) { + return compare(v[0], 44, bitwidth) && compare(v[1], 45, bitwidth); +} +template bool check_2d(const T (&v)[3][2][N], unsigned int bitwidth) { + return compare(v[0][1], 46, bitwidth) && compare(v[1][1], 47, bitwidth) + && compare(v[2][1], 48, bitwidth); +} +template bool check_3d(const T (&v)[4][3][2][N], unsigned int bitwidth) { + return compare(v[0][0][0], 49, bitwidth) && compare(v[1][0][0], 50, bitwidth) + && compare(v[2][0][0], 51, bitwidth) && compare(v[3][0][0], 52, bitwidth); +} + +} // unnamed namespace + +void* get_non_null() { + static int v; + return &v; +} + +void i_byte_0d(char* v) { + if (!update_0d(v)) stop(); +} +void i_byte_1d(char* v) { + if (!update_1d(v)) stop(); +} +void i_byte_2d(char* v) { + if (!update_2d(v)) stop(); +} +void i_byte_3d(char* v) { + if (!update_3d(v)) stop(); +} + +void i_byte_unsigned_0d(unsigned char* v) { + if (!update_0d(v)) stop(); +} +void i_byte_unsigned_1d(unsigned char* v) { + if (!update_1d(v)) stop(); +} +void i_byte_unsigned_2d(unsigned char* v) { + if (!update_2d(v)) stop(); +} +void i_byte_unsigned_3d(unsigned char* v) { + if (!update_3d(v)) stop(); +} + +void i_shortint_0d(short* v) { + if (!update_0d(v)) stop(); +} +void i_shortint_1d(short* v) { + if (!update_1d(v)) stop(); +} +void i_shortint_2d(short* v) { + if (!update_2d(v)) stop(); +} +void i_shortint_3d(short* v) { + if (!update_3d(v)) stop(); +} + +void i_shortint_unsigned_0d(unsigned short* v) { + if (!update_0d(v)) stop(); +} +void i_shortint_unsigned_1d(unsigned short* v) { + if (!update_1d(v)) stop(); +} +void i_shortint_unsigned_2d(unsigned short* v) { + if (!update_2d(v)) stop(); +} +void i_shortint_unsigned_3d(unsigned short* v) { + if (!update_3d(v)) stop(); +} + +void i_int_0d(int* v) { + if (!update_0d(v)) stop(); +} +void i_int_1d(int* v) { + if (!update_1d(v)) stop(); +} +void i_int_2d(int* v) { + if (!update_2d(v)) stop(); +} +void i_int_3d(int* v) { + if (!update_3d(v)) stop(); +} + +void i_int_unsigned_0d(unsigned int* v) { + if (!update_0d(v)) stop(); +} +void i_int_unsigned_1d(unsigned int* v) { + if (!update_1d(v)) stop(); +} +void i_int_unsigned_2d(unsigned int* v) { + if (!update_2d(v)) stop(); +} +void i_int_unsigned_3d(unsigned int* v) { + if (!update_3d(v)) stop(); +} + +void i_longint_0d(sv_longint_t* v) { + if (!update_0d(v)) stop(); +} +void i_longint_1d(sv_longint_t* v) { + if (!update_1d(v)) stop(); +} +void i_longint_2d(sv_longint_t* v) { + if (!update_2d(v)) stop(); +} +void i_longint_3d(sv_longint_t* v) { + if (!update_3d(v)) stop(); +} + +void i_longint_unsigned_0d(sv_longint_unsigned_t* v) { + if (!update_0d(v)) stop(); +} +void i_longint_unsigned_1d(sv_longint_unsigned_t* v) { + if (!update_1d(v)) stop(); +} +void i_longint_unsigned_2d(sv_longint_unsigned_t* v) { + if (!update_2d(v)) stop(); +} +void i_longint_unsigned_3d(sv_longint_unsigned_t* v) { + if (!update_3d(v)) stop(); +} + +#ifndef NO_TIME +void i_time_0d(svLogicVecVal* v) { + if (!update_0d(v, 64)) stop(); +} +void i_time_1d(svLogicVecVal* v) { + if (!update_1d(v, 64)) stop(); +} +void i_time_2d(svLogicVecVal* v) { + if (!update_2d(v, 64)) stop(); +} +void i_time_3d(svLogicVecVal* v) { + if (!update_3d(v, 64)) stop(); +} +#endif + +#ifndef NO_INTEGER +void i_integer_0d(svLogicVecVal* v) { + if (!update_0d(v, 32)) stop(); +} +void i_integer_1d(svLogicVecVal* v) { + if (!update_1d(v, 32)) stop(); +} +void i_integer_2d(svLogicVecVal* v) { + if (!update_2d(v, 32)) stop(); +} +void i_integer_3d(svLogicVecVal* v) { + if (!update_3d(v, 32)) stop(); +} +#endif + +void i_real_0d(double* v) { update_0d(v); } +void i_real_1d(double* v) { update_1d(v); } +void i_real_2d(double* v) { update_2d(v); } +void i_real_3d(double* v) { update_3d(v); } + +#ifndef NO_SHORTREAL +void i_shortreal_0d(float* v) { update_0d(v); } +void i_shortreal_1d(float* v) { update_1d(v); } +void i_shortreal_2d(float* v) { update_2d(v); } +void i_shortreal_3d(float* v) { update_3d(v); } +#endif + +void i_chandle_0d(void** v) { + if (v[0]) stop(); + v[0] = get_non_null(); +} +void i_chandle_1d(void** v) { + if (v[0]) stop(); + if (v[1]) stop(); + v[0] = get_non_null(); + v[1] = get_non_null(); +} +void i_chandle_2d(void** v) { + if (v[2 * 0 + 1]) stop(); + if (v[2 * 1 + 1]) stop(); + if (v[2 * 2 + 1]) stop(); + v[2 * 0 + 1] = get_non_null(); + v[2 * 1 + 1] = get_non_null(); + v[2 * 2 + 1] = get_non_null(); +} +void i_chandle_3d(void** v) { + if (v[(0 * 3 + 0) * 2 + 0]) stop(); + if (v[(1 * 3 + 0) * 2 + 0]) stop(); + if (v[(2 * 3 + 0) * 2 + 0]) stop(); + if (v[(3 * 3 + 0) * 2 + 0]) stop(); + v[(0 * 3 + 0) * 2 + 0] = get_non_null(); + v[(1 * 3 + 0) * 2 + 0] = get_non_null(); + v[(2 * 3 + 0) * 2 + 0] = get_non_null(); + v[(3 * 3 + 0) * 2 + 0] = get_non_null(); +} + +void i_string_0d(const char** v) { + static const char s[] = "43"; + if (!compare(v[0], "42")) stop(); + v[0] = s; +} +void i_string_1d(const char** v) { + static const char s0[] = "44"; + static const char s1[] = "45"; + if (!compare(v[0], "43")) stop(); + if (!compare(v[1], "44")) stop(); + v[0] = s0; + v[1] = s1; +} +void i_string_2d(const char** v) { + static const char s0[] = "46"; + static const char s1[] = "47"; + static const char s2[] = "48"; + if (!compare(v[2 * 0 + 1], "45")) stop(); + if (!compare(v[2 * 1 + 1], "46")) stop(); + if (!compare(v[2 * 2 + 1], "47")) stop(); + v[2 * 0 + 1] = s0; + v[2 * 1 + 1] = s1; + v[2 * 2 + 1] = s2; +} +void i_string_3d(const char** v) { + static const char s0[] = "49"; + static const char s1[] = "50"; + static const char s2[] = "51"; + static const char s3[] = "52"; + if (!compare(v[(0 * 3 + 0) * 2 + 0], "48")) stop(); + if (!compare(v[(1 * 3 + 0) * 2 + 0], "49")) stop(); + if (!compare(v[(2 * 3 + 0) * 2 + 0], "50")) stop(); + if (!compare(v[(3 * 3 + 0) * 2 + 0], "51")) stop(); + v[(0 * 3 + 0) * 2 + 0] = s0; + v[(1 * 3 + 0) * 2 + 0] = s1; + v[(2 * 3 + 0) * 2 + 0] = s2; + v[(3 * 3 + 0) * 2 + 0] = s3; +} + +void i_bit7_0d(svBitVecVal* v) { update_0d(v, 7); } +void i_bit7_1d(svBitVecVal* v) { update_1d(v, 7); } +void i_bit7_2d(svBitVecVal* v) { update_2d(v, 7); } +void i_bit7_3d(svBitVecVal* v) { update_3d(v, 7); } + +void i_bit121_0d(svBitVecVal* v) { update_0d(v, 121); } +void i_bit121_1d(svBitVecVal* v) { update_1d(v, 121); } +void i_bit121_2d(svBitVecVal* v) { update_2d(v, 121); } +void i_bit121_3d(svBitVecVal* v) { update_3d(v, 121); } + +void i_logic7_0d(svLogicVecVal* v) { update_0d(v, 7); } +void i_logic7_1d(svLogicVecVal* v) { update_1d(v, 7); } +void i_logic7_2d(svLogicVecVal* v) { update_2d(v, 7); } +void i_logic7_3d(svLogicVecVal* v) { update_3d(v, 7); } + +void i_logic121_0d(svLogicVecVal* v) { update_0d(v, 121); } +void i_logic121_1d(svLogicVecVal* v) { update_1d(v, 121); } +void i_logic121_2d(svLogicVecVal* v) { update_2d(v, 121); } +void i_logic121_3d(svLogicVecVal* v) { update_3d(v, 121); } + +void i_pack_struct_0d(svLogicVecVal* v) { update_0d(v, 7); } +void i_pack_struct_1d(svLogicVecVal* v) { update_1d(v, 7); } +void i_pack_struct_2d(svLogicVecVal* v) { update_2d(v, 7); } +void i_pack_struct_3d(svLogicVecVal* v) { update_3d(v, 7); } + +#ifndef NO_UNPACK_STRUCT +void i_unpack_struct_0d(unpack_struct_t* v) { + if (!compare(v->val, 42, 121)) stop(); + set_uint(v->val, 43, 121); +} +void i_unpack_struct_1d(unpack_struct_t* v) { + if (!compare(v[0].val, 43, 121)) stop(); + if (!compare(v[1].val, 44, 121)) stop(); + set_uint(v[0].val, 44, 121); + set_uint(v[1].val, 45, 121); +} +void i_unpack_struct_2d(unpack_struct_t* v) { + if (!compare(v[0 * 2 + 1].val, 45, 121)) stop(); + if (!compare(v[1 * 2 + 1].val, 46, 121)) stop(); + if (!compare(v[2 * 2 + 1].val, 47, 121)) stop(); + set_uint(v[0 * 2 + 1].val, 46, 121); + set_uint(v[1 * 2 + 1].val, 47, 121); + set_uint(v[2 * 2 + 1].val, 48, 121); +} +void i_unpack_struct_3d(unpack_struct_t* v) { + if (!compare(v[(0 * 3 + 0) * 2 + 0].val, 48, 121)) stop(); + if (!compare(v[(1 * 3 + 0) * 2 + 0].val, 49, 121)) stop(); + if (!compare(v[(2 * 3 + 0) * 2 + 0].val, 50, 121)) stop(); + if (!compare(v[(3 * 3 + 0) * 2 + 0].val, 51, 121)) stop(); + set_uint(v[(0 * 3 + 0) * 2 + 0].val, 49, 121); + set_uint(v[(1 * 3 + 0) * 2 + 0].val, 50, 121); + set_uint(v[(2 * 3 + 0) * 2 + 0].val, 51, 121); + set_uint(v[(3 * 3 + 0) * 2 + 0].val, 52, 121); +} +#endif + +void check_exports() { + { + char byte_array[4][3][2]; + set_values(byte_array); + e_byte_0d(&byte_array[3][2][1]); + if (!check_0d(byte_array[3][2][1])) stop(); + e_byte_1d(&byte_array[2][1][0]); + if (!check_1d(byte_array[2][1])) stop(); + e_byte_2d(&byte_array[1][0][0]); + if (!check_2d(byte_array[1])) stop(); + e_byte_3d(&byte_array[0][0][0]); + if (!check_3d(byte_array)) stop(); + } + { + unsigned char byte_unsigned_array[4][3][2]; + set_values(byte_unsigned_array); + e_byte_unsigned_0d(&byte_unsigned_array[3][2][1]); + if (!check_0d(byte_unsigned_array[3][2][1])) stop(); + e_byte_unsigned_1d(&byte_unsigned_array[2][1][0]); + if (!check_1d(byte_unsigned_array[2][1])) stop(); + e_byte_unsigned_2d(&byte_unsigned_array[1][0][0]); + if (!check_2d(byte_unsigned_array[1])) stop(); + e_byte_unsigned_3d(&byte_unsigned_array[0][0][0]); + if (!check_3d(byte_unsigned_array)) stop(); + } + { + short shortint_array[4][3][2]; + set_values(shortint_array); + e_shortint_0d(&shortint_array[3][2][1]); + if (!check_0d(shortint_array[3][2][1])) stop(); + e_shortint_1d(&shortint_array[2][1][0]); + if (!check_1d(shortint_array[2][1])) stop(); + e_shortint_2d(&shortint_array[1][0][0]); + if (!check_2d(shortint_array[1])) stop(); + e_shortint_3d(&shortint_array[0][0][0]); + if (!check_3d(shortint_array)) stop(); + } + { + unsigned short shortint_unsigned_array[4][3][2]; + set_values(shortint_unsigned_array); + e_shortint_unsigned_0d(&shortint_unsigned_array[3][2][1]); + if (!check_0d(shortint_unsigned_array[3][2][1])) stop(); + e_shortint_unsigned_1d(&shortint_unsigned_array[2][1][0]); + if (!check_1d(shortint_unsigned_array[2][1])) stop(); + e_shortint_unsigned_2d(&shortint_unsigned_array[1][0][0]); + if (!check_2d(shortint_unsigned_array[1])) stop(); + e_shortint_unsigned_3d(&shortint_unsigned_array[0][0][0]); + if (!check_3d(shortint_unsigned_array)) stop(); + } + + { + int int_array[4][3][2]; + set_values(int_array); + e_int_0d(&int_array[3][2][1]); + if (!check_0d(int_array[3][2][1])) stop(); + e_int_1d(&int_array[2][1][0]); + if (!check_1d(int_array[2][1])) stop(); + e_int_2d(&int_array[1][0][0]); + if (!check_2d(int_array[1])) stop(); + e_int_3d(&int_array[0][0][0]); + if (!check_3d(int_array)) stop(); + } + { + unsigned int int_unsigned_array[4][3][2]; + set_values(int_unsigned_array); + e_int_unsigned_0d(&int_unsigned_array[3][2][1]); + if (!check_0d(int_unsigned_array[3][2][1])) stop(); + e_int_unsigned_1d(&int_unsigned_array[2][1][0]); + if (!check_1d(int_unsigned_array[2][1])) stop(); + e_int_unsigned_2d(&int_unsigned_array[1][0][0]); + if (!check_2d(int_unsigned_array[1])) stop(); + e_int_unsigned_3d(&int_unsigned_array[0][0][0]); + if (!check_3d(int_unsigned_array)) stop(); + } + + { + sv_longint_t longint_array[4][3][2]; + set_values(longint_array); + e_longint_0d(&longint_array[3][2][1]); + if (!check_0d(longint_array[3][2][1])) stop(); + e_longint_1d(&longint_array[2][1][0]); + if (!check_1d(longint_array[2][1])) stop(); + e_longint_2d(&longint_array[1][0][0]); + if (!check_2d(longint_array[1])) stop(); + e_longint_3d(&longint_array[0][0][0]); + if (!check_3d(longint_array)) stop(); + } + { + sv_longint_unsigned_t longint_unsigned_array[4][3][2]; + set_values(longint_unsigned_array); + e_longint_unsigned_0d(&longint_unsigned_array[3][2][1]); + if (!check_0d(longint_unsigned_array[3][2][1])) stop(); + e_longint_unsigned_1d(&longint_unsigned_array[2][1][0]); + if (!check_1d(longint_unsigned_array[2][1])) stop(); + e_longint_unsigned_2d(&longint_unsigned_array[1][0][0]); + if (!check_2d(longint_unsigned_array[1])) stop(); + e_longint_unsigned_3d(&longint_unsigned_array[0][0][0]); + if (!check_3d(longint_unsigned_array)) stop(); + } + +#ifndef NO_TIME + { + svLogicVecVal time_array[4][3][2][2]; + set_values(time_array, 64); + e_time_0d(time_array[3][2][1]); + if (!check_0d(time_array[3][2][1], 64)) stop(); + e_time_1d(time_array[2][1][0]); + if (!check_1d(time_array[2][1], 64)) stop(); + e_time_2d(time_array[1][0][0]); + if (!check_2d(time_array[1], 64)) stop(); + e_time_3d(time_array[0][0][0]); + if (!check_3d(time_array, 64)) stop(); + } +#endif + +#ifndef NO_INTEGER + { + svLogicVecVal integer_array[4][3][2][1]; + set_values(integer_array, 32); + e_integer_0d(integer_array[3][2][1]); + if (!check_0d(integer_array[3][2][1], 32)) stop(); + e_integer_1d(integer_array[2][1][0]); + if (!check_1d(integer_array[2][1], 32)) stop(); + e_integer_2d(integer_array[1][0][0]); + if (!check_2d(integer_array[1], 32)) stop(); + e_integer_3d(integer_array[0][0][0]); + if (!check_3d(integer_array, 32)) stop(); + } +#endif + + { + double real_array[4][3][2]; + set_values(real_array); + e_real_0d(&real_array[3][2][1]); + if (!check_0d(real_array[3][2][1])) stop(); + e_real_1d(&real_array[2][1][0]); + if (!check_1d(real_array[2][1])) stop(); + e_real_2d(&real_array[1][0][0]); + if (!check_2d(real_array[1])) stop(); + e_real_3d(&real_array[0][0][0]); + if (!check_3d(real_array)) stop(); + } +#ifndef NO_SHORTREAL + { + float shortreal_array[4][3][2]; + set_values(shortreal_array); + e_shortreal_0d(&shortreal_array[3][2][1]); + if (!check_0d(shortreal_array[3][2][1])) stop(); + e_shortreal_1d(&shortreal_array[2][1][0]); + if (!check_1d(shortreal_array[2][1])) stop(); + e_shortreal_2d(&shortreal_array[1][0][0]); + if (!check_2d(shortreal_array[1])) stop(); + e_shortreal_3d(&shortreal_array[0][0][0]); + if (!check_3d(shortreal_array)) stop(); + } +#endif + + { + void* chandle_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) chandle_array[i][j][k] = NULL; + chandle_array[3][2][1] = get_non_null(); + e_chandle_0d(&chandle_array[3][2][1]); + if (chandle_array[3][2][1]) stop(); + + chandle_array[2][1][0] = get_non_null(); + chandle_array[2][1][1] = get_non_null(); + e_chandle_1d(&chandle_array[2][1][0]); + if (chandle_array[2][1][0]) stop(); + if (chandle_array[2][1][1]) stop(); + + chandle_array[1][0][1] = get_non_null(); + chandle_array[1][1][1] = get_non_null(); + chandle_array[1][2][1] = get_non_null(); + e_chandle_2d(&chandle_array[1][0][0]); + if (chandle_array[1][0][1]) stop(); + if (chandle_array[1][1][1]) stop(); + if (chandle_array[1][2][1]) stop(); + + chandle_array[0][0][0] = get_non_null(); + chandle_array[1][0][0] = get_non_null(); + chandle_array[2][0][0] = get_non_null(); + chandle_array[3][0][0] = get_non_null(); + e_chandle_3d(&chandle_array[0][0][0]); + if (chandle_array[0][0][0]) stop(); + if (chandle_array[1][0][0]) stop(); + if (chandle_array[2][0][0]) stop(); + if (chandle_array[3][0][0]) stop(); + } + + { + const char* string_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) string_array[i][j][k] = ""; + string_array[3][2][1] = "42"; + e_string_0d(&string_array[3][2][1]); + if (!compare(string_array[3][2][1], "43")) stop(); + + string_array[2][1][0] = "43"; + string_array[2][1][1] = "44"; + e_string_1d(&string_array[2][1][0]); + if (!compare(string_array[2][1][0], "44")) stop(); + if (!compare(string_array[2][1][1], "45")) stop(); + + string_array[1][0][1] = "45"; + string_array[1][1][1] = "46"; + string_array[1][2][1] = "47"; + e_string_2d(&string_array[1][0][0]); + if (!compare(string_array[1][0][1], "46")) stop(); + if (!compare(string_array[1][1][1], "47")) stop(); + if (!compare(string_array[1][2][1], "48")) stop(); + + string_array[0][0][0] = "48"; + string_array[1][0][0] = "49"; + string_array[2][0][0] = "50"; + string_array[3][0][0] = "51"; + e_string_3d(&string_array[0][0][0]); + if (!compare(string_array[0][0][0], "49")) stop(); + if (!compare(string_array[1][0][0], "50")) stop(); + if (!compare(string_array[2][0][0], "51")) stop(); + if (!compare(string_array[3][0][0], "52")) stop(); + } + + { + svBitVecVal bit7_array[4][3][2][1]; + set_values(bit7_array, 7); + e_bit7_0d(bit7_array[3][2][1]); + if (!check_0d(bit7_array[3][2][1], 7)) stop(); + e_bit7_1d(bit7_array[2][1][0]); + if (!check_1d(bit7_array[2][1], 7)) stop(); + e_bit7_2d(bit7_array[1][0][0]); + if (!check_2d(bit7_array[1], 7)) stop(); + e_bit7_3d(bit7_array[0][0][0]); + if (!check_3d(bit7_array, 7)) stop(); + } + { + svBitVecVal bit121_array[4][3][2][4]; + set_values(bit121_array, 121); + e_bit121_0d(bit121_array[3][2][1]); + if (!check_0d(bit121_array[3][2][1], 121)) stop(); + e_bit121_1d(bit121_array[2][1][0]); + if (!check_1d(bit121_array[2][1], 121)) stop(); + e_bit121_2d(bit121_array[1][0][0]); + if (!check_2d(bit121_array[1], 121)) stop(); + e_bit121_3d(bit121_array[0][0][0]); + if (!check_3d(bit121_array, 121)) stop(); + } + + { + svLogicVecVal logic7_array[4][3][2][1]; + set_values(logic7_array, 7); + e_logic7_0d(logic7_array[3][2][1]); + if (!check_0d(logic7_array[3][2][1], 7)) stop(); + e_logic7_1d(logic7_array[2][1][0]); + if (!check_1d(logic7_array[2][1], 7)) stop(); + e_logic7_2d(logic7_array[1][0][0]); + if (!check_2d(logic7_array[1], 7)) stop(); + e_logic7_3d(logic7_array[0][0][0]); + if (!check_3d(logic7_array, 7)) stop(); + } + { + svLogicVecVal logic121_array[4][3][2][4]; + set_values(logic121_array, 121); + e_logic121_0d(logic121_array[3][2][1]); + if (!check_0d(logic121_array[3][2][1], 121)) stop(); + e_logic121_1d(logic121_array[2][1][0]); + if (!check_1d(logic121_array[2][1], 121)) stop(); + e_logic121_2d(logic121_array[1][0][0]); + if (!check_2d(logic121_array[1], 121)) stop(); + e_logic121_3d(logic121_array[0][0][0]); + if (!check_3d(logic121_array, 121)) stop(); + } + + { + svLogicVecVal pack_struct_array[4][3][2][1]; + set_values(pack_struct_array, 7); + e_pack_struct_0d(pack_struct_array[3][2][1]); + if (!check_0d(pack_struct_array[3][2][1], 7)) stop(); + e_pack_struct_1d(pack_struct_array[2][1][0]); + if (!check_1d(pack_struct_array[2][1], 7)) stop(); + e_pack_struct_2d(pack_struct_array[1][0][0]); + if (!check_2d(pack_struct_array[1], 7)) stop(); + e_pack_struct_3d(pack_struct_array[0][0][0]); + if (!check_3d(pack_struct_array, 7)) stop(); + } + +#ifndef NO_UNPACK_STRUCT + { + unpack_struct_t unpack_struct_array[4][3][2]; + set_uint(unpack_struct_array[3][2][1].val, 42, 121); + e_unpack_struct_0d(&unpack_struct_array[3][2][1]); + if (!compare(unpack_struct_array[3][2][1].val, 43, 121)) stop(); + + set_uint(unpack_struct_array[2][1][0].val, 43, 121); + set_uint(unpack_struct_array[2][1][1].val, 44, 121); + e_unpack_struct_1d(&unpack_struct_array[2][1][0]); + if (!compare(unpack_struct_array[2][1][0].val, 44, 121)) stop(); + if (!compare(unpack_struct_array[2][1][1].val, 45, 121)) stop(); + + set_uint(unpack_struct_array[1][0][1].val, 45, 121); + set_uint(unpack_struct_array[1][1][1].val, 46, 121); + set_uint(unpack_struct_array[1][2][1].val, 47, 121); + e_unpack_struct_2d(&unpack_struct_array[1][0][0]); + if (!compare(unpack_struct_array[1][0][1].val, 46, 121)) stop(); + if (!compare(unpack_struct_array[1][1][1].val, 47, 121)) stop(); + if (!compare(unpack_struct_array[1][2][1].val, 48, 121)) stop(); + + set_uint(unpack_struct_array[0][0][0].val, 48, 121); + set_uint(unpack_struct_array[1][0][0].val, 49, 121); + set_uint(unpack_struct_array[2][0][0].val, 50, 121); + set_uint(unpack_struct_array[3][0][0].val, 51, 121); + e_unpack_struct_3d(&unpack_struct_array[0][0][0]); + if (!compare(unpack_struct_array[0][0][0].val, 49, 121)) stop(); + if (!compare(unpack_struct_array[1][0][0].val, 50, 121)) stop(); + if (!compare(unpack_struct_array[2][0][0].val, 51, 121)) stop(); + if (!compare(unpack_struct_array[3][0][0].val, 52, 121)) stop(); + } +#endif +} diff --git a/test_regress/t/t_dpi_arg_inout_unpack.pl b/test_regress/t/t_dpi_arg_inout_unpack.pl new file mode 100755 index 000000000..59dfe0252 --- /dev/null +++ b/test_regress/t/t_dpi_arg_inout_unpack.pl @@ -0,0 +1,44 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +if ($Self->{nc}) { + # For NC, compile twice, first just to generate DPI headers + compile( + nc_flags2 => ["+ncdpiheader+$Self->{obj_dir}/dpi-exp.h", + "+ncdpiimpheader+$Self->{obj_dir}/dpi-imp.h"] + ); +} + +compile( + v_flags2 => ["t/t_dpi_arg_inout_unpack.cpp"], + verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], + # NC: Gdd the obj_dir to the C include path + nc_flags2 => ["+ncscargs+-I$Self->{obj_dir}"], + # ModelSim: Generate DPI header, add obj_dir to the C include path + ms_flags2 => ["-dpiheader $Self->{obj_dir}/dpi.h", + "-ccflags -I$Self->{obj_dir}"], + ); + +if ($Self->{vlt_all}) { + files_identical( + "$Self->{obj_dir}/Vt_dpi_arg_inout_unpack__Dpi.h", + "t/t_dpi_arg_inout_unpack__Dpi.out" + ); +} + +execute( + check_finished => 1, + ms_pli => 0 + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_arg_inout_unpack.v b/test_regress/t/t_dpi_arg_inout_unpack.v new file mode 100644 index 000000000..a37a24cc2 --- /dev/null +++ b/test_regress/t/t_dpi_arg_inout_unpack.v @@ -0,0 +1,1162 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +`ifdef VCS + `define NO_TIME +`endif + +`ifdef NC + `define NO_TIME + `define NO_INTEGER + `define NO_SHORTREAL +`endif + +`ifdef MS +`endif + +`ifdef VERILATOR + `define NO_SHORTREAL + `define NO_UNPACK_STRUCT +//%Error-TASKNSVAR: Unsupported: Function/task input argument is not simple variable + `define NO_INOUT_COMPLEX_TYPE +`else +`endif + +`define CHECK_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":", (act), " as expected"); \ + end else begin \ + $display("Mismatch %s expected:%d actual:%d at %d", `"act`", int'(exp), int'(act), `__LINE__); \ + $stop; \ + end + +`define CHECK_CHANDLE_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":non-null as expected"); \ + end else begin \ + $display("Mismatch %s expected:%s but %s at %d", `"act`", \ + (exp) != null ? "null" : "non-null", \ + (act) != null ? "null" : "non-null", `__LINE__); \ + $stop; \ + end + +`define CHECK_STRING_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":", (act), " as expected"); \ + end else begin \ + $display("Mismatch %s expected:%s actual:%s at %d", `"act`", (exp), (act), `__LINE__); \ + $stop; \ + end + +`define UPDATE_VAL(var, val) `CHECK_VAL(var, val); var += 1 +`define UPDATE_0D(val) `UPDATE_VAL(val, 42) +`define UPDATE_1D(val) `UPDATE_VAL(val[0], 43); \ +`UPDATE_VAL(val[1], 44) +`define UPDATE_2D(val) `UPDATE_VAL(val[0][1], 45); \ +`UPDATE_VAL(val[1][1], 46); \ +`UPDATE_VAL(val[2][1], 47) +`define UPDATE_3D(val) `UPDATE_VAL(val[0][0][0], 48); \ +`UPDATE_VAL(val[1][0][0], 49); \ +`UPDATE_VAL(val[2][0][0], 50); \ +`UPDATE_VAL(val[3][0][0], 51) + +`define CHECK_0D(val) `CHECK_VAL((val), 43) +`define CHECK_1D(val) `CHECK_VAL(val[0], 44); \ +`CHECK_VAL(val[1], 45) +`define CHECK_2D(val) `CHECK_VAL(val[0][1], 46); \ +`CHECK_VAL(val[1][1], 47); `CHECK_VAL(val[2][1], 48) +`define CHECK_3D(val) `CHECK_VAL(val[0][0][0], 49); \ +`CHECK_VAL(val[1][0][0], 50); \ +`CHECK_VAL(val[2][0][0], 51); \ +`CHECK_VAL(val[3][0][0], 52) + +`define CHECK_DOUBLE_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display("%s:%f as expected", `"act`", (act)); \ + end else begin \ + $display("Mismatch %s expected:%d actual:%f at %f", `"act`", (exp), (act), `__LINE__); \ + $stop; \ + end + +`define CHECK_DOUBLE_0D(val) `CHECK_DOUBLE_VAL((val), 43.0) +`define CHECK_DOUBLE_1D(val) `CHECK_DOUBLE_VAL(val[0], 44.0); \ +`CHECK_DOUBLE_VAL(val[1], 45.0) +`define CHECK_DOUBLE_2D(val) `CHECK_DOUBLE_VAL(val[0][1], 46.0); \ +`CHECK_DOUBLE_VAL(val[1][1], 47.0); \ +`CHECK_DOUBLE_VAL(val[2][1], 48.0) +`define CHECK_DOUBLE_3D(val) `CHECK_DOUBLE_VAL(val[0][0][0], 49.0); \ +`CHECK_DOUBLE_VAL(val[1][0][0], 50.0); \ +`CHECK_DOUBLE_VAL(val[2][0][0], 51.0); \ +`CHECK_DOUBLE_VAL(val[3][0][0], 52.0) + +`define SET_VALUE_0D(val) val = 42 +`define SET_VALUE_1D(val) val[0] = 43; val[1] = 44 +`define SET_VALUE_2D(val) val[0][1] = 45; val[1][1] = 46; val[2][1] = 47 +`define SET_VALUES(val) \ +val[3][2][1] = 42; \ +val[2][1][0] = 43; val[2][1][1] = 44; \ +val[1][0][1] = 45; val[1][1][1] = 46; val[1][2][1] = 47; \ +val[0][0][0] = 48; val[1][0][0] = 49; val[2][0][0] = 50; val[3][0][0] = 51 + +module t; + + localparam ENABLE_VERBOSE_MESSAGE = 0; + + // Legal output argument types for DPI functions + + //====================================================================== + // Type definitions + //====================================================================== + + typedef byte byte_t; + typedef byte_t byte_array_t[4][3][2]; + typedef byte unsigned byte_unsigned_t; + typedef byte_unsigned_t byte_unsigned_array_t[4][3][2]; + typedef shortint shortint_t; + typedef shortint_t shortint_array_t[4][3][2]; + typedef shortint unsigned shortint_unsigned_t; + typedef shortint_unsigned_t shortint_unsigned_array_t[4][3][2]; + typedef int int_t; + typedef int_t int_array_t[4][3][2]; + typedef int unsigned int_unsigned_t; + typedef int_unsigned_t int_unsigned_array_t[4][3][2]; + typedef longint longint_t; + typedef longint_t longint_array_t[4][3][2]; + typedef longint unsigned longint_unsigned_t; + typedef longint_unsigned_t longint_unsigned_array_t[4][3][2]; +`ifndef NO_TIME + typedef time time_t; + typedef time_t time_array_t[4][3][2]; +`endif +`ifndef NO_INTEGER + typedef integer integer_t; + typedef integer_t integer_array_t[4][3][2]; +`endif + typedef real real_t; + typedef real_t real_array_t[4][3][2]; +`ifndef NO_SHORTREAL + typedef shortreal shortreal_t; + typedef shortreal_t shortreal_array_t[4][3][2]; +`endif + typedef chandle chandle_t; + typedef chandle_t chandle_array_t[4][3][2]; + typedef string string_t; + typedef string_t string_array_t[4][3][2]; + typedef bit [6:0] bit7_t; + typedef bit7_t bit7_array_t[4][3][2]; + typedef bit [120:0] bit121_t; + typedef bit121_t bit121_array_t[4][3][2]; + typedef logic [6:0] logic7_t; + typedef logic7_t logic7_array_t[4][3][2]; + typedef logic [120:0] logic121_t; + typedef logic121_t logic121_array_t[4][3][2]; + + typedef struct packed { + logic [6:0] val; + } pack_struct_t; + typedef pack_struct_t pack_struct_array_t[4][3][2]; +`ifndef NO_UNPACK_STRUCT + typedef struct { + logic [120:0] val; + } unpack_struct_t; + typedef unpack_struct_t unpack_struct_array_t[4][3][2]; +`endif + + //====================================================================== + // Imports + //====================================================================== + + // Returns non-null pointer + import "DPI-C" function chandle get_non_null(); + + import "DPI-C" function void i_byte_0d(inout byte_t val); + import "DPI-C" function void i_byte_1d(inout byte_t val[2]); + import "DPI-C" function void i_byte_2d(inout byte_t val[3][2]); + import "DPI-C" function void i_byte_3d(inout byte_array_t val); + + import "DPI-C" function void i_byte_unsigned_0d(inout byte unsigned val); + import "DPI-C" function void i_byte_unsigned_1d(inout byte unsigned val[2]); + import "DPI-C" function void i_byte_unsigned_2d(inout byte unsigned val[3][2]); + import "DPI-C" function void i_byte_unsigned_3d(inout byte_unsigned_array_t val); + + import "DPI-C" function void i_shortint_0d(inout shortint val); + import "DPI-C" function void i_shortint_1d(inout shortint val[2]); + import "DPI-C" function void i_shortint_2d(inout shortint val[3][2]); + import "DPI-C" function void i_shortint_3d(inout shortint_array_t val); + + import "DPI-C" function void i_shortint_unsigned_0d(inout shortint unsigned val); + import "DPI-C" function void i_shortint_unsigned_1d(inout shortint unsigned val[2]); + import "DPI-C" function void i_shortint_unsigned_2d(inout shortint unsigned val[3][2]); + import "DPI-C" function void i_shortint_unsigned_3d(inout shortint_unsigned_array_t val); + + import "DPI-C" function void i_int_0d(inout int val); + import "DPI-C" function void i_int_1d(inout int val[2]); + import "DPI-C" function void i_int_2d(inout int val[3][2]); + import "DPI-C" function void i_int_3d(inout int_array_t val); + + import "DPI-C" function void i_int_unsigned_0d(inout int unsigned val); + import "DPI-C" function void i_int_unsigned_1d(inout int unsigned val[2]); + import "DPI-C" function void i_int_unsigned_2d(inout int unsigned val[3][2]); + import "DPI-C" function void i_int_unsigned_3d(inout int_unsigned_array_t val); + + import "DPI-C" function void i_longint_0d(inout longint val); + import "DPI-C" function void i_longint_1d(inout longint val[2]); + import "DPI-C" function void i_longint_2d(inout longint val[3][2]); + import "DPI-C" function void i_longint_3d(inout longint_array_t val); + + import "DPI-C" function void i_longint_unsigned_0d(inout longint unsigned val); + import "DPI-C" function void i_longint_unsigned_1d(inout longint unsigned val[2]); + import "DPI-C" function void i_longint_unsigned_2d(inout longint unsigned val[3][2]); + import "DPI-C" function void i_longint_unsigned_3d(inout longint_unsigned_array_t val); + +`ifndef NO_TIME + import "DPI-C" function void i_time_0d(inout time val); + import "DPI-C" function void i_time_1d(inout time val[2]); + import "DPI-C" function void i_time_2d(inout time val[3][2]); + import "DPI-C" function void i_time_3d(inout time_array_t val); +`endif + +`ifndef NO_INTEGER + import "DPI-C" function void i_integer_0d(inout integer val); + import "DPI-C" function void i_integer_1d(inout integer val[2]); + import "DPI-C" function void i_integer_2d(inout integer val[3][2]); + import "DPI-C" function void i_integer_3d(inout integer_array_t val); +`endif + + import "DPI-C" function void i_real_0d(inout real val); + import "DPI-C" function void i_real_1d(inout real val[2]); + import "DPI-C" function void i_real_2d(inout real val[3][2]); + import "DPI-C" function void i_real_3d(inout real_array_t val); + +`ifndef NO_SHORTREAL + import "DPI-C" function void i_shortreal_0d(inout shortreal val); + import "DPI-C" function void i_shortreal_1d(inout shortreal val[2]); + import "DPI-C" function void i_shortreal_2d(inout shortreal val[3][2]); + import "DPI-C" function void i_shortreal_3d(inout shortreal_array_t val); +`endif + + import "DPI-C" function void i_chandle_0d(inout chandle val); + import "DPI-C" function void i_chandle_1d(inout chandle val[2]); + import "DPI-C" function void i_chandle_2d(inout chandle val[3][2]); + import "DPI-C" function void i_chandle_3d(inout chandle_array_t val); + + import "DPI-C" function void i_string_0d(inout string val); + import "DPI-C" function void i_string_1d(inout string val[2]); + import "DPI-C" function void i_string_2d(inout string val[3][2]); + import "DPI-C" function void i_string_3d(inout string_array_t val); + + import "DPI-C" function void i_bit7_0d(inout bit[6:0] val); + import "DPI-C" function void i_bit7_1d(inout bit[6:0] val[2]); + import "DPI-C" function void i_bit7_2d(inout bit[6:0] val[3][2]); + import "DPI-C" function void i_bit7_3d(inout bit7_array_t val); + + import "DPI-C" function void i_bit121_0d(inout bit[120:0] val); + import "DPI-C" function void i_bit121_1d(inout bit[120:0] val[2]); + import "DPI-C" function void i_bit121_2d(inout bit[120:0] val[3][2]); + import "DPI-C" function void i_bit121_3d(inout bit121_array_t val); + + import "DPI-C" function void i_logic7_0d(inout logic[6:0] val); + import "DPI-C" function void i_logic7_1d(inout logic[6:0] val[2]); + import "DPI-C" function void i_logic7_2d(inout logic[6:0] val[3][2]); + import "DPI-C" function void i_logic7_3d(inout logic7_array_t val); + + import "DPI-C" function void i_logic121_0d(inout logic[120:0] val); + import "DPI-C" function void i_logic121_1d(inout logic[120:0] val[2]); + import "DPI-C" function void i_logic121_2d(inout logic[120:0] val[3][2]); + import "DPI-C" function void i_logic121_3d(inout logic121_array_t val); + + import "DPI-C" function void i_pack_struct_0d(inout pack_struct_t val); + import "DPI-C" function void i_pack_struct_1d(inout pack_struct_t val[2]); + import "DPI-C" function void i_pack_struct_2d(inout pack_struct_t val[3][2]); + import "DPI-C" function void i_pack_struct_3d(inout pack_struct_array_t val); + +`ifndef NO_UNPACK_STRUCT + import "DPI-C" function void i_unpack_struct_0d(inout unpack_struct_t val); + import "DPI-C" function void i_unpack_struct_1d(inout unpack_struct_t val[2]); + import "DPI-C" function void i_unpack_struct_2d(inout unpack_struct_t val[3][2]); + import "DPI-C" function void i_unpack_struct_3d(inout unpack_struct_array_t val); +`endif + + //====================================================================== + // Exports + //====================================================================== + export "DPI-C" function e_byte_0d; + export "DPI-C" function e_byte_1d; + export "DPI-C" function e_byte_2d; + export "DPI-C" function e_byte_3d; + + export "DPI-C" function e_byte_unsigned_0d; + export "DPI-C" function e_byte_unsigned_1d; + export "DPI-C" function e_byte_unsigned_2d; + export "DPI-C" function e_byte_unsigned_3d; + + export "DPI-C" function e_shortint_0d; + export "DPI-C" function e_shortint_1d; + export "DPI-C" function e_shortint_2d; + export "DPI-C" function e_shortint_3d; + + export "DPI-C" function e_shortint_unsigned_0d; + export "DPI-C" function e_shortint_unsigned_1d; + export "DPI-C" function e_shortint_unsigned_2d; + export "DPI-C" function e_shortint_unsigned_3d; + + export "DPI-C" function e_int_0d; + export "DPI-C" function e_int_1d; + export "DPI-C" function e_int_2d; + export "DPI-C" function e_int_3d; + + export "DPI-C" function e_int_unsigned_0d; + export "DPI-C" function e_int_unsigned_1d; + export "DPI-C" function e_int_unsigned_2d; + export "DPI-C" function e_int_unsigned_3d; + + export "DPI-C" function e_longint_0d; + export "DPI-C" function e_longint_1d; + export "DPI-C" function e_longint_2d; + export "DPI-C" function e_longint_3d; + + export "DPI-C" function e_longint_unsigned_0d; + export "DPI-C" function e_longint_unsigned_1d; + export "DPI-C" function e_longint_unsigned_2d; + export "DPI-C" function e_longint_unsigned_3d; + +`ifndef NO_TIME + export "DPI-C" function e_time_0d; + export "DPI-C" function e_time_1d; + export "DPI-C" function e_time_2d; + export "DPI-C" function e_time_3d; +`endif + +`ifndef NO_INTEGER + export "DPI-C" function e_integer_0d; + export "DPI-C" function e_integer_1d; + export "DPI-C" function e_integer_2d; + export "DPI-C" function e_integer_3d; +`endif + + export "DPI-C" function e_real_0d; + export "DPI-C" function e_real_1d; + export "DPI-C" function e_real_2d; + export "DPI-C" function e_real_3d; + +`ifndef NO_SHORTREAL + export "DPI-C" function e_shortreal_0d; + export "DPI-C" function e_shortreal_1d; + export "DPI-C" function e_shortreal_2d; + export "DPI-C" function e_shortreal_3d; +`endif + + export "DPI-C" function e_chandle_0d; + export "DPI-C" function e_chandle_1d; + export "DPI-C" function e_chandle_2d; + export "DPI-C" function e_chandle_3d; + + export "DPI-C" function e_string_0d; + export "DPI-C" function e_string_1d; + export "DPI-C" function e_string_2d; + export "DPI-C" function e_string_3d; + + export "DPI-C" function e_bit7_0d; + export "DPI-C" function e_bit7_1d; + export "DPI-C" function e_bit7_2d; + export "DPI-C" function e_bit7_3d; + + export "DPI-C" function e_bit121_0d; + export "DPI-C" function e_bit121_1d; + export "DPI-C" function e_bit121_2d; + export "DPI-C" function e_bit121_3d; + + export "DPI-C" function e_logic7_0d; + export "DPI-C" function e_logic7_1d; + export "DPI-C" function e_logic7_2d; + export "DPI-C" function e_logic7_3d; + + export "DPI-C" function e_logic121_0d; + export "DPI-C" function e_logic121_1d; + export "DPI-C" function e_logic121_2d; + export "DPI-C" function e_logic121_3d; + + export "DPI-C" function e_pack_struct_0d; + export "DPI-C" function e_pack_struct_1d; + export "DPI-C" function e_pack_struct_2d; + export "DPI-C" function e_pack_struct_3d; + +`ifndef NO_UNPACK_STRUCT + export "DPI-C" function e_unpack_struct_0d; + export "DPI-C" function e_unpack_struct_1d; + export "DPI-C" function e_unpack_struct_2d; + export "DPI-C" function e_unpack_struct_3d; +`endif + //====================================================================== + // Definitions of exported functions + //====================================================================== + + function void e_byte_0d(inout byte val); `UPDATE_0D(val); endfunction + function void e_byte_1d(inout byte val[2]); `UPDATE_1D(val); endfunction + function void e_byte_2d(inout byte val[3][2]); `UPDATE_2D(val); endfunction + function void e_byte_3d(inout byte_array_t val); `UPDATE_3D(val); endfunction + + function void e_byte_unsigned_0d(inout byte unsigned val); `UPDATE_0D(val); endfunction + function void e_byte_unsigned_1d(inout byte unsigned val[2]); `UPDATE_1D(val); endfunction + function void e_byte_unsigned_2d(inout byte unsigned val[3][2]); `UPDATE_2D(val); endfunction + function void e_byte_unsigned_3d(inout byte_unsigned_array_t val); `UPDATE_3D(val); endfunction + + function void e_shortint_0d(inout shortint val); `UPDATE_0D(val); endfunction + function void e_shortint_1d(inout shortint val[2]); `UPDATE_1D(val); endfunction + function void e_shortint_2d(inout shortint val[3][2]); `UPDATE_2D(val); endfunction + function void e_shortint_3d(inout shortint_array_t val); `UPDATE_3D(val); endfunction + + function void e_shortint_unsigned_0d(inout shortint unsigned val); `UPDATE_0D(val); endfunction + function void e_shortint_unsigned_1d(inout shortint unsigned val[2]); `UPDATE_1D(val); endfunction + function void e_shortint_unsigned_2d(inout shortint unsigned val[3][2]); `UPDATE_2D(val); endfunction + function void e_shortint_unsigned_3d(inout shortint_unsigned_array_t val); `UPDATE_3D(val); endfunction + + + function void e_int_0d(inout int val); `UPDATE_0D(val); endfunction + function void e_int_1d(inout int val[2]); `UPDATE_1D(val); endfunction + function void e_int_2d(inout int val[3][2]); `UPDATE_2D(val); endfunction + function void e_int_3d(inout int_array_t val); `UPDATE_3D(val); endfunction + + function void e_int_unsigned_0d(inout int unsigned val); `UPDATE_0D(val); endfunction + function void e_int_unsigned_1d(inout int unsigned val[2]); `UPDATE_1D(val); endfunction + function void e_int_unsigned_2d(inout int unsigned val[3][2]); `UPDATE_2D(val); endfunction + function void e_int_unsigned_3d(inout int_unsigned_array_t val); `UPDATE_3D(val); endfunction + + + + function void e_longint_0d(inout longint val); `UPDATE_0D(val); endfunction + function void e_longint_1d(inout longint val[2]); `UPDATE_1D(val); endfunction + function void e_longint_2d(inout longint val[3][2]); `UPDATE_2D(val); endfunction + function void e_longint_3d(inout longint_array_t val); `UPDATE_3D(val); endfunction + + function void e_longint_unsigned_0d(inout longint unsigned val); `UPDATE_0D(val); endfunction + function void e_longint_unsigned_1d(inout longint unsigned val[2]); `UPDATE_1D(val); endfunction + function void e_longint_unsigned_2d(inout longint unsigned val[3][2]); `UPDATE_2D(val); endfunction + function void e_longint_unsigned_3d(inout longint_unsigned_array_t val); `UPDATE_3D(val); endfunction + +`ifndef NO_TIME + function void e_time_0d(inout time val); `UPDATE_0D(val); endfunction + function void e_time_1d(inout time val[2]); `UPDATE_1D(val); endfunction + function void e_time_2d(inout time val[3][2]); `UPDATE_2D(val); endfunction + function void e_time_3d(inout time_array_t val); `UPDATE_3D(val); endfunction +`endif + +`ifndef NO_INTEGER + function void e_integer_0d(inout integer val); `UPDATE_0D(val); endfunction + function void e_integer_1d(inout integer val[2]); `UPDATE_1D(val); endfunction + function void e_integer_2d(inout integer val[3][2]); `UPDATE_2D(val); endfunction + function void e_integer_3d(inout integer_array_t val); `UPDATE_3D(val); endfunction +`endif + + function void e_real_0d(inout real val); `UPDATE_0D(val); endfunction + function void e_real_1d(inout real val[2]); `UPDATE_1D(val); endfunction + function void e_real_2d(inout real val[3][2]); `UPDATE_2D(val); endfunction + function void e_real_3d(inout real_array_t val); `UPDATE_3D(val); endfunction + +`ifndef NO_SHORTREAL + function void e_shortreal_0d(inout shortreal val); `UPDATE_0D(val); endfunction + function void e_shortreal_1d(inout shortreal val[2]); `UPDATE_1D(val); endfunction + function void e_shortreal_2d(inout shortreal val[3][2]); `UPDATE_2D(val); endfunction + function void e_shortreal_3d(inout shortreal_array_t val); `UPDATE_3D(val); endfunction +`endif + + + function void e_chandle_0d(inout chandle val); + `CHECK_CHANDLE_VAL(val, get_non_null()); + val = null; + endfunction + function void e_chandle_1d(inout chandle val[2]); + `CHECK_CHANDLE_VAL(val[0], get_non_null()); + `CHECK_CHANDLE_VAL(val[1], get_non_null()); + val[0] = null; + val[1] = null; + endfunction + function void e_chandle_2d(inout chandle val[3][2]); + `CHECK_CHANDLE_VAL(val[0][1], get_non_null()); + `CHECK_CHANDLE_VAL(val[1][1], get_non_null()); + `CHECK_CHANDLE_VAL(val[2][1], get_non_null()); + val[0][1] = null; + val[1][1] = null; + val[2][1] = null; + endfunction + function void e_chandle_3d(inout chandle_array_t val); + `CHECK_CHANDLE_VAL(val[0][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(val[1][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(val[2][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(val[3][0][0], get_non_null()); + val[0][0][0] = null; + val[1][0][0] = null; + val[2][0][0] = null; + val[3][0][0] = null; + endfunction + + + function void e_string_0d(inout string val); + `CHECK_STRING_VAL(val, "42"); + val = "43"; + endfunction + function void e_string_1d(inout string val[2]); + `CHECK_STRING_VAL(val[0], "43"); + `CHECK_STRING_VAL(val[1], "44"); + val[0] = "44"; + val[1] = "45"; + endfunction + function void e_string_2d(inout string val[3][2]); + `CHECK_STRING_VAL(val[0][1], "45"); + `CHECK_STRING_VAL(val[1][1], "46"); + `CHECK_STRING_VAL(val[2][1], "47"); + val[0][1] = "46"; + val[1][1] = "47"; + val[2][1] = "48"; + endfunction + function void e_string_3d(inout string_array_t val); + `CHECK_STRING_VAL(val[0][0][0], "48"); + `CHECK_STRING_VAL(val[1][0][0], "49"); + `CHECK_STRING_VAL(val[2][0][0], "50"); + `CHECK_STRING_VAL(val[3][0][0], "51"); + val[0][0][0] = "49"; + val[1][0][0] = "50"; + val[2][0][0] = "51"; + val[3][0][0] = "52"; + endfunction + + function void e_bit7_0d(inout bit[6:0] val); `UPDATE_0D(val); endfunction + function void e_bit7_1d(inout bit[6:0] val[2]); `UPDATE_1D(val); endfunction + function void e_bit7_2d(inout bit[6:0] val[3][2]); `UPDATE_2D(val); endfunction + function void e_bit7_3d(inout bit7_array_t val); `UPDATE_3D(val); endfunction + + function void e_bit121_0d(inout bit[120:0] val); `UPDATE_0D(val); endfunction + function void e_bit121_1d(inout bit[120:0] val[2]); `UPDATE_1D(val); endfunction + function void e_bit121_2d(inout bit[120:0] val[3][2]); `UPDATE_2D(val); endfunction + function void e_bit121_3d(inout bit121_array_t val); `UPDATE_3D(val); endfunction + + function void e_logic7_0d(inout logic[6:0] val); `UPDATE_0D(val); endfunction + function void e_logic7_1d(inout logic[6:0] val[2]); `UPDATE_1D(val); endfunction + function void e_logic7_2d(inout logic[6:0] val[3][2]); `UPDATE_2D(val); endfunction + function void e_logic7_3d(inout logic7_array_t val); `UPDATE_3D(val); endfunction + + function void e_logic121_0d(inout logic[120:0] val); `UPDATE_0D(val); endfunction + function void e_logic121_1d(inout logic[120:0] val[2]); `UPDATE_1D(val); endfunction + function void e_logic121_2d(inout logic[120:0] val[3][2]); `UPDATE_2D(val); endfunction + function void e_logic121_3d(inout logic121_array_t val); `UPDATE_3D(val); endfunction + + function void e_pack_struct_0d(inout pack_struct_t val); `UPDATE_0D(val); endfunction + function void e_pack_struct_1d(inout pack_struct_t val[2]); `UPDATE_1D(val); endfunction + function void e_pack_struct_2d(inout pack_struct_t val[3][2]); `UPDATE_2D(val); endfunction + function void e_pack_struct_3d(inout pack_struct_array_t val); `UPDATE_3D(val); endfunction + +`ifndef NO_UNPACK_STRUCT + function void e_unpack_struct_0d(inout unpack_struct_t val); + `CHECK_VAL(val.val, 42); + val.val = 43; + endfunction + function void e_unpack_struct_1d(inout unpack_struct_t val[2]); + `CHECK_VAL(val[0].val, 43); + `CHECK_VAL(val[1].val, 44); + val[0].val = 44; + val[1].val = 45; + endfunction + function void e_unpack_struct_2d(inout unpack_struct_t val[3][2]); + `CHECK_VAL(val[0][1].val, 45); + `CHECK_VAL(val[1][1].val, 46); + `CHECK_VAL(val[2][1].val, 47); + val[0][1].val = 46; + val[1][1].val = 47; + val[2][1].val = 48; + endfunction + function void e_unpack_struct_3d(inout unpack_struct_array_t val); + `CHECK_VAL(val[0][0][0].val, 48); + `CHECK_VAL(val[1][0][0].val, 49); + `CHECK_VAL(val[2][0][0].val, 50); + `CHECK_VAL(val[3][0][0].val, 51); + val[0][0][0].val = 49; + val[1][0][0].val = 50; + val[2][0][0].val = 51; + val[3][0][0].val = 52; + endfunction +`endif + + //====================================================================== + // Invoke all imported functions + //====================================================================== + + import "DPI-C" context function void check_exports(); + initial begin + byte_t byte_array_0d; + byte_t byte_array_1d[2]; + byte_t byte_array_2d[3][2]; + byte_array_t byte_array; + byte_unsigned_t byte_unsigned_array_0d; + byte_unsigned_t byte_unsigned_array_1d[2]; + byte_unsigned_t byte_unsigned_array_2d[3][2]; + byte_unsigned_array_t byte_unsigned_array; + shortint_t shortint_array_0d; + shortint_t shortint_array_1d[2]; + shortint_t shortint_array_2d[3][2]; + shortint_array_t shortint_array; + shortint_unsigned_t shortint_unsigned_array_0d; + shortint_unsigned_t shortint_unsigned_array_1d[2]; + shortint_unsigned_t shortint_unsigned_array_2d[3][2]; + shortint_unsigned_array_t shortint_unsigned_array; + int_t int_array_0d; + int_t int_array_1d[2]; + int_t int_array_2d[3][2]; + int_array_t int_array; + int_unsigned_t int_unsigned_array_0d; + int_unsigned_t int_unsigned_array_1d[2]; + int_unsigned_t int_unsigned_array_2d[3][2]; + int_unsigned_array_t int_unsigned_array; + longint_t longint_array_0d; + longint_t longint_array_1d[2]; + longint_t longint_array_2d[3][2]; + longint_array_t longint_array; + longint_unsigned_t longint_unsigned_array_0d; + longint_unsigned_t longint_unsigned_array_1d[2]; + longint_unsigned_t longint_unsigned_array_2d[3][2]; + longint_unsigned_array_t longint_unsigned_array; +`ifndef NO_TIME + time_t time_array_0d; + time_t time_array_1d[2]; + time_t time_array_2d[3][2]; + time_array_t time_array; +`endif +`ifndef NO_INTEGER + integer_t integer_array_0d; + integer_t integer_array_1d[2]; + integer_t integer_array_2d[3][2]; + integer_array_t integer_array; +`endif + real_t real_array_0d; + real_t real_array_1d[2]; + real_t real_array_2d[3][2]; + real_array_t real_array; +`ifndef NO_SHORTREAL + shortreal_t shortreal_array_0d; + shortreal_t shortreal_array_1d[2]; + shortreal_t shortreal_array_2d[3][2]; + shortreal_array_t shortreal_array; +`endif + chandle_t chandle_array_0d; + chandle_t chandle_array_1d[2]; + chandle_t chandle_array_2d[3][2]; + chandle_array_t chandle_array; + + string_t string_array_0d; + string_t string_array_1d[2]; + string_t string_array_2d[3][2]; + string_array_t string_array; + + bit7_t bit7_array_0d; + bit7_t bit7_array_1d[2]; + bit7_t bit7_array_2d[3][2]; + bit7_array_t bit7_array; + + bit121_t bit121_array_0d; + bit121_t bit121_array_1d[2]; + bit121_t bit121_array_2d[3][2]; + bit121_array_t bit121_array; + + logic7_t logic7_array_0d; + logic7_t logic7_array_1d[2]; + logic7_t logic7_array_2d[3][2]; + logic7_array_t logic7_array; + + logic121_t logic121_array_0d; + logic121_t logic121_array_1d[2]; + logic121_t logic121_array_2d[3][2]; + logic121_array_t logic121_array; + + pack_struct_t pack_struct_array_0d; + pack_struct_t pack_struct_array_1d[2]; + pack_struct_t pack_struct_array_2d[3][2]; + pack_struct_array_t pack_struct_array; + +`ifndef NO_UNPACK_STRUCT + unpack_struct_t unpack_struct_array_0d; + unpack_struct_t unpack_struct_array_1d[2]; + unpack_struct_t unpack_struct_array_2d[3][2]; + unpack_struct_array_t unpack_struct_array; +`endif + + `SET_VALUES(byte_array); + `SET_VALUE_0D(byte_array_0d); + `SET_VALUE_1D(byte_array_1d); + `SET_VALUE_2D(byte_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_byte_0d(byte_array[3][2][1]); + `CHECK_0D(byte_array[3][2][1]); + i_byte_1d(byte_array[2][1]); + `CHECK_1D(byte_array[2][1]); + i_byte_2d(byte_array[1]); + `CHECK_2D(byte_array[1]); +`endif + i_byte_0d(byte_array_0d); + `CHECK_0D(byte_array_0d); + i_byte_1d(byte_array_1d); + `CHECK_1D(byte_array_1d); + i_byte_2d(byte_array_2d); + `CHECK_2D(byte_array_2d); + i_byte_3d(byte_array); + `CHECK_3D(byte_array); + + `SET_VALUES(byte_unsigned_array); + `SET_VALUE_0D(byte_unsigned_array_0d); + `SET_VALUE_1D(byte_unsigned_array_1d); + `SET_VALUE_2D(byte_unsigned_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_byte_unsigned_0d(byte_unsigned_array[3][2][1]); + `CHECK_0D(byte_unsigned_array[3][2][1]); + i_byte_unsigned_1d(byte_unsigned_array[2][1]); + `CHECK_1D(byte_unsigned_array[2][1]); + i_byte_unsigned_2d(byte_unsigned_array[1]); + `CHECK_2D(byte_unsigned_array[1]); +`endif + i_byte_unsigned_0d(byte_unsigned_array_0d); + `CHECK_0D(byte_unsigned_array_0d); + i_byte_unsigned_1d(byte_unsigned_array_1d); + `CHECK_1D(byte_unsigned_array_1d); + i_byte_unsigned_2d(byte_unsigned_array_2d); + `CHECK_2D(byte_unsigned_array_2d); + i_byte_unsigned_3d(byte_unsigned_array); + `CHECK_3D(byte_unsigned_array); + + `SET_VALUES(shortint_array); + `SET_VALUE_0D(shortint_array_0d); + `SET_VALUE_1D(shortint_array_1d); + `SET_VALUE_2D(shortint_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_shortint_0d(shortint_array[3][2][1]); + `CHECK_0D(shortint_array[3][2][1]); + i_shortint_1d(shortint_array[2][1]); + `CHECK_1D(shortint_array[2][1]); + i_shortint_2d(shortint_array[1]); + `CHECK_2D(shortint_array[1]); +`endif + i_shortint_0d(shortint_array_0d); + `CHECK_0D(shortint_array_0d); + i_shortint_1d(shortint_array_1d); + `CHECK_1D(shortint_array_1d); + i_shortint_2d(shortint_array_2d); + `CHECK_2D(shortint_array_2d); + i_shortint_3d(shortint_array); + `CHECK_3D(shortint_array); + + `SET_VALUES(shortint_unsigned_array); + `SET_VALUE_0D(shortint_unsigned_array_0d); + `SET_VALUE_1D(shortint_unsigned_array_1d); + `SET_VALUE_2D(shortint_unsigned_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_shortint_unsigned_0d(shortint_unsigned_array[3][2][1]); + `CHECK_0D(shortint_unsigned_array[3][2][1]); + i_shortint_unsigned_1d(shortint_unsigned_array[2][1]); + `CHECK_1D(shortint_unsigned_array[2][1]); + i_shortint_unsigned_2d(shortint_unsigned_array[1]); + `CHECK_2D(shortint_unsigned_array[1]); +`endif + i_shortint_unsigned_0d(shortint_unsigned_array_0d); + `CHECK_0D(shortint_unsigned_array_0d); + i_shortint_unsigned_1d(shortint_unsigned_array_1d); + `CHECK_1D(shortint_unsigned_array_1d); + i_shortint_unsigned_2d(shortint_unsigned_array_2d); + `CHECK_2D(shortint_unsigned_array_2d); + i_shortint_unsigned_3d(shortint_unsigned_array); + `CHECK_3D(shortint_unsigned_array); + + `SET_VALUES(int_array); + `SET_VALUE_0D(int_array_0d); + `SET_VALUE_1D(int_array_1d); + `SET_VALUE_2D(int_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_int_0d(int_array[3][2][1]); + `CHECK_0D(int_array[3][2][1]); + i_int_1d(int_array[2][1]); + `CHECK_1D(int_array[2][1]); + i_int_2d(int_array[1]); + `CHECK_2D(int_array[1]); +`endif + i_int_0d(int_array_0d); + `CHECK_0D(int_array_0d); + i_int_1d(int_array_1d); + `CHECK_1D(int_array_1d); + i_int_2d(int_array_2d); + `CHECK_2D(int_array_2d); + i_int_3d(int_array); + `CHECK_3D(int_array); + + `SET_VALUES(int_unsigned_array); + `SET_VALUE_0D(int_unsigned_array_0d); + `SET_VALUE_1D(int_unsigned_array_1d); + `SET_VALUE_2D(int_unsigned_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_int_unsigned_0d(int_unsigned_array[3][2][1]); + `CHECK_0D(int_unsigned_array[3][2][1]); + i_int_unsigned_1d(int_unsigned_array[2][1]); + `CHECK_1D(int_unsigned_array[2][1]); + i_int_unsigned_2d(int_unsigned_array[1]); + `CHECK_2D(int_unsigned_array[1]); +`endif + i_int_unsigned_0d(int_unsigned_array_0d); + `CHECK_0D(int_unsigned_array_0d); + i_int_unsigned_1d(int_unsigned_array_1d); + `CHECK_1D(int_unsigned_array_1d); + i_int_unsigned_2d(int_unsigned_array_2d); + `CHECK_2D(int_unsigned_array_2d); + i_int_unsigned_3d(int_unsigned_array); + `CHECK_3D(int_unsigned_array); + + `SET_VALUES(longint_array); + `SET_VALUE_0D(longint_array_0d); + `SET_VALUE_1D(longint_array_1d); + `SET_VALUE_2D(longint_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_longint_0d(longint_array[3][2][1]); + `CHECK_0D(longint_array[3][2][1]); + i_longint_1d(longint_array[2][1]); + `CHECK_1D(longint_array[2][1]); + i_longint_2d(longint_array[1]); + `CHECK_2D(longint_array[1]); +`endif + i_longint_0d(longint_array_0d); + `CHECK_0D(longint_array_0d); + i_longint_1d(longint_array_1d); + `CHECK_1D(longint_array_1d); + i_longint_2d(longint_array_2d); + `CHECK_2D(longint_array_2d); + i_longint_3d(longint_array); + `CHECK_3D(longint_array); + + `SET_VALUES(longint_unsigned_array); + `SET_VALUE_0D(longint_unsigned_array_0d); + `SET_VALUE_1D(longint_unsigned_array_1d); + `SET_VALUE_2D(longint_unsigned_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_longint_unsigned_0d(longint_unsigned_array[3][2][1]); + `CHECK_0D(longint_unsigned_array[3][2][1]); + i_longint_unsigned_1d(longint_unsigned_array[2][1]); + `CHECK_1D(longint_unsigned_array[2][1]); + i_longint_unsigned_2d(longint_unsigned_array[1]); + `CHECK_2D(longint_unsigned_array[1]); +`endif + i_longint_unsigned_0d(longint_unsigned_array_0d); + `CHECK_0D(longint_unsigned_array_0d); + i_longint_unsigned_1d(longint_unsigned_array_1d); + `CHECK_1D(longint_unsigned_array_1d); + i_longint_unsigned_2d(longint_unsigned_array_2d); + `CHECK_2D(longint_unsigned_array_2d); + i_longint_unsigned_3d(longint_unsigned_array); + `CHECK_3D(longint_unsigned_array); + +`ifndef NO_TIME + `SET_VALUES(time_array); + `SET_VALUE_0D(time_array_0d); + `SET_VALUE_1D(time_array_1d); + `SET_VALUE_2D(time_array_2d); + `ifndef NO_INOUT_COMPLEX_TYPE + i_time_0d(time_array[3][2][1]); + `CHECK_0D(time_array[3][2][1]); + i_time_1d(time_array[2][1]); + `CHECK_1D(time_array[2][1]); + i_time_2d(time_array[1]); + `CHECK_2D(time_array[1]); + `endif + i_time_0d(time_array_0d); + `CHECK_0D(time_array_0d); + i_time_1d(time_array_1d); + `CHECK_1D(time_array_1d); + i_time_2d(time_array_2d); + `CHECK_2D(time_array_2d); + i_time_3d(time_array); + `CHECK_3D(time_array); +`endif + +`ifndef NO_INTEGER + `SET_VALUES(integer_array); + `SET_VALUE_0D(integer_array_0d); + `SET_VALUE_1D(integer_array_1d); + `SET_VALUE_2D(integer_array_2d); + `ifndef NO_INOUT_COMPLEX_TYPE + i_integer_0d(integer_array[3][2][1]); + `CHECK_0D(integer_array[3][2][1]); + i_integer_1d(integer_array[2][1]); + `CHECK_1D(integer_array[2][1]); + i_integer_2d(integer_array[1]); + `CHECK_2D(integer_array[1]); + `endif + i_integer_0d(integer_array_0d); + `CHECK_0D(integer_array_0d); + i_integer_1d(integer_array_1d); + `CHECK_1D(integer_array_1d); + i_integer_2d(integer_array_2d); + `CHECK_2D(integer_array_2d); + i_integer_3d(integer_array); + `CHECK_3D(integer_array); +`endif + + `SET_VALUES(real_array); + `SET_VALUE_0D(real_array_0d); + `SET_VALUE_1D(real_array_1d); + `SET_VALUE_2D(real_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_real_0d(real_array[3][2][1]); + `CHECK_DOUBLE_0D(real_array[3][2][1]); + i_real_1d(real_array[2][1]); + `CHECK_DOUBLE_1D(real_array[2][1]); + i_real_2d(real_array[1]); + `CHECK_DOUBLE_2D(real_array[1]); +`endif + i_real_0d(real_array_0d); + `CHECK_DOUBLE_0D(real_array_0d); + i_real_1d(real_array_1d); + `CHECK_DOUBLE_1D(real_array_1d); + i_real_2d(real_array_2d); + `CHECK_DOUBLE_2D(real_array_2d); + i_real_3d(real_array); + `CHECK_DOUBLE_3D(real_array); + +`ifndef NO_SHORTREAL + `SET_VALUES(shortreal_array); + `SET_VALUE_0D(shortreal_array_0d); + `SET_VALUE_1D(shortreal_array_1d); + `SET_VALUE_2D(shortreal_array_2d); + `ifndef NO_INOUT_COMPLEX_TYPE + i_shortreal_0d(shortreal_array[3][2][1]); + `CHECK_DOUBLE_0D(shortreal_array[3][2][1]); + i_shortreal_1d(shortreal_array[2][1]); + `CHECK_DOUBLE_1D(shortreal_array[2][1]); + i_shortreal_2d(shortreal_array[1]); + `CHECK_DOUBLE_2D(shortreal_array[1]); + `endif + i_shortreal_0d(shortreal_array_0d); + `CHECK_DOUBLE_0D(shortreal_array_0d); + i_shortreal_1d(shortreal_array_1d); + `CHECK_DOUBLE_1D(shortreal_array_1d); + i_shortreal_2d(shortreal_array_2d); + `CHECK_DOUBLE_2D(shortreal_array_2d); + i_shortreal_3d(shortreal_array); + `CHECK_DOUBLE_3D(shortreal_array); +`endif + + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) + chandle_array[i][j][k] = null; +`ifndef NO_INOUT_COMPLEX_TYPE + i_chandle_0d(chandle_array[3][2][1]); + `CHECK_CHANDLE_VAL(chandle_array[3][2][1], get_non_null()); + i_chandle_1d(chandle_array[2][1]); + `CHECK_CHANDLE_VAL(chandle_array[2][1][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[2][1][1], get_non_null()); + i_chandle_2d(chandle_array[1]); + `CHECK_CHANDLE_VAL(chandle_array[1][0][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][1][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][2][1], get_non_null()); +`endif + chandle_array_0d = null; + i_chandle_0d(chandle_array_0d); + `CHECK_CHANDLE_VAL(chandle_array_0d, get_non_null()); + chandle_array_1d[0] = null; + chandle_array_1d[1] = null; + i_chandle_1d(chandle_array_1d); + `CHECK_CHANDLE_VAL(chandle_array_1d[0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array_1d[1], get_non_null()); + chandle_array_2d[0][1] = null; + chandle_array_2d[1][1] = null; + chandle_array_2d[2][1] = null; + i_chandle_2d(chandle_array_2d); + `CHECK_CHANDLE_VAL(chandle_array_2d[0][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array_2d[1][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array_2d[2][1], get_non_null()); + i_chandle_3d(chandle_array); + `CHECK_CHANDLE_VAL(chandle_array[0][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[2][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[3][0][0], get_non_null()); + +`ifndef NO_INOUT_COMPLEX_TYPE + string_array[3][2][1] = "42"; + i_string_0d(string_array[3][2][1]); + `CHECK_STRING_VAL(string_array[3][2][1], "43"); + + string_array[2][1][0] = "43"; + string_array[2][1][1] = "44"; + i_string_1d(string_array[2][1]); + `CHECK_STRING_VAL(string_array[2][1][0], "44"); + `CHECK_STRING_VAL(string_array[2][1][1], "45"); + + string_array[1][0][1] = "45"; + string_array[1][1][1] = "46"; + string_array[1][2][1] = "47"; + i_string_2d(string_array[1]); + `CHECK_STRING_VAL(string_array[1][0][1], "46"); + `CHECK_STRING_VAL(string_array[1][1][1], "47"); + `CHECK_STRING_VAL(string_array[1][2][1], "48"); +`endif + string_array_0d = "42"; + i_string_0d(string_array_0d); + `CHECK_STRING_VAL(string_array_0d, "43"); + string_array_1d[0] = "43"; + string_array_1d[1] = "44"; + i_string_1d(string_array_1d); + `CHECK_STRING_VAL(string_array_1d[0], "44"); + `CHECK_STRING_VAL(string_array_1d[1], "45"); + + string_array_2d[0][1] = "45"; + string_array_2d[1][1] = "46"; + string_array_2d[2][1] = "47"; + i_string_2d(string_array_2d); + `CHECK_STRING_VAL(string_array_2d[0][1], "46"); + `CHECK_STRING_VAL(string_array_2d[1][1], "47"); + `CHECK_STRING_VAL(string_array_2d[2][1], "48"); + + string_array[0][0][0] = "48"; + string_array[1][0][0] = "49"; + string_array[2][0][0] = "50"; + string_array[3][0][0] = "51"; + i_string_3d(string_array); + `CHECK_STRING_VAL(string_array[0][0][0], "49"); + `CHECK_STRING_VAL(string_array[1][0][0], "50"); + `CHECK_STRING_VAL(string_array[2][0][0], "51"); + `CHECK_STRING_VAL(string_array[3][0][0], "52"); + + `SET_VALUES(bit7_array); + `SET_VALUE_0D(bit7_array_0d); + `SET_VALUE_1D(bit7_array_1d); + `SET_VALUE_2D(bit7_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_bit7_0d(bit7_array[3][2][1]); + `CHECK_0D(bit7_array[3][2][1]); + i_bit7_1d(bit7_array[2][1]); + `CHECK_1D(bit7_array[2][1]); + i_bit7_2d(bit7_array[1]); + `CHECK_2D(bit7_array[1]); +`endif + i_bit7_0d(bit7_array_0d); + `CHECK_0D(bit7_array_0d); + i_bit7_1d(bit7_array_1d); + `CHECK_1D(bit7_array_1d); + i_bit7_2d(bit7_array_2d); + `CHECK_2D(bit7_array_2d); + i_bit7_3d(bit7_array); + `CHECK_3D(bit7_array); + + `SET_VALUES(bit121_array); + `SET_VALUE_0D(bit121_array_0d); + `SET_VALUE_1D(bit121_array_1d); + `SET_VALUE_2D(bit121_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_bit121_0d(bit121_array[3][2][1]); + `CHECK_0D(bit121_array[3][2][1]); + i_bit121_1d(bit121_array[2][1]); + `CHECK_1D(bit121_array[2][1]); + i_bit121_2d(bit121_array[1]); + `CHECK_2D(bit121_array[1]); +`endif + i_bit121_0d(bit121_array_0d); + `CHECK_0D(bit121_array_0d); + i_bit121_1d(bit121_array_1d); + `CHECK_1D(bit121_array_1d); + i_bit121_2d(bit121_array_2d); + `CHECK_2D(bit121_array_2d); + i_bit121_3d(bit121_array); + `CHECK_3D(bit121_array); + + `SET_VALUES(logic7_array); + `SET_VALUE_0D(logic7_array_0d); + `SET_VALUE_1D(logic7_array_1d); + `SET_VALUE_2D(logic7_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_logic7_0d(logic7_array[3][2][1]); + `CHECK_0D(logic7_array[3][2][1]); + i_logic7_1d(logic7_array[2][1]); + `CHECK_1D(logic7_array[2][1]); + i_logic7_2d(logic7_array[1]); + `CHECK_2D(logic7_array[1]); +`endif + i_logic7_0d(logic7_array_0d); + `CHECK_0D(logic7_array_0d); + i_logic7_1d(logic7_array_1d); + `CHECK_1D(logic7_array_1d); + i_logic7_2d(logic7_array_2d); + `CHECK_2D(logic7_array_2d); + i_logic7_3d(logic7_array); + `CHECK_3D(logic7_array); + + `SET_VALUES(logic121_array); + `SET_VALUE_0D(logic121_array_0d); + `SET_VALUE_1D(logic121_array_1d); + `SET_VALUE_2D(logic121_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_logic121_0d(logic121_array[3][2][1]); + `CHECK_0D(logic121_array[3][2][1]); + i_logic121_1d(logic121_array[2][1]); + `CHECK_1D(logic121_array[2][1]); + i_logic121_2d(logic121_array[1]); + `CHECK_2D(logic121_array[1]); +`endif + i_logic121_0d(logic121_array_0d); + `CHECK_0D(logic121_array_0d); + i_logic121_1d(logic121_array_1d); + `CHECK_1D(logic121_array_1d); + i_logic121_2d(logic121_array_2d); + `CHECK_2D(logic121_array_2d); + i_logic121_3d(logic121_array); + `CHECK_3D(logic121_array); + + `SET_VALUES(pack_struct_array); + `SET_VALUE_0D(pack_struct_array_0d); + `SET_VALUE_1D(pack_struct_array_1d); + `SET_VALUE_2D(pack_struct_array_2d); +`ifndef NO_INOUT_COMPLEX_TYPE + i_pack_struct_0d(pack_struct_array[3][2][1]); + `CHECK_0D(pack_struct_array[3][2][1]); + i_pack_struct_1d(pack_struct_array[2][1]); + `CHECK_1D(pack_struct_array[2][1]); + i_pack_struct_2d(pack_struct_array[1]); + `CHECK_2D(pack_struct_array[1]); +`endif + i_pack_struct_0d(pack_struct_array_0d); + `CHECK_0D(pack_struct_array_0d); + i_pack_struct_1d(pack_struct_array_1d); + `CHECK_1D(pack_struct_array_1d); + i_pack_struct_2d(pack_struct_array_2d); + `CHECK_2D(pack_struct_array_2d); + i_pack_struct_3d(pack_struct_array); + `CHECK_3D(pack_struct_array); + +`ifndef NO_UNPACK_STRUCT + unpack_struct_array[3][2][1].val = 42; + i_unpack_struct_0d(unpack_struct_array[3][2][1]); + `CHECK_VAL(unpack_struct_array[3][2][1].val, 43); + + unpack_struct_array[2][1][0].val = 43; + unpack_struct_array[2][1][1].val = 44; + i_unpack_struct_1d(unpack_struct_array[2][1]); + `CHECK_VAL(unpack_struct_array[2][1][0].val, 44); + `CHECK_VAL(unpack_struct_array[2][1][1].val, 45); + + unpack_struct_array[1][0][1].val = 45; + unpack_struct_array[1][1][1].val = 46; + unpack_struct_array[1][2][1].val = 47; + i_unpack_struct_2d(unpack_struct_array[1]); + `CHECK_VAL(unpack_struct_array[1][0][1].val, 46); + `CHECK_VAL(unpack_struct_array[1][1][1].val, 47); + `CHECK_VAL(unpack_struct_array[1][2][1].val, 48); + + unpack_struct_array[0][0][0].val = 48; + unpack_struct_array[1][0][0].val = 49; + unpack_struct_array[2][0][0].val = 50; + unpack_struct_array[3][0][0].val = 51; + i_unpack_struct_3d(unpack_struct_array); + `CHECK_VAL(unpack_struct_array[0][0][0].val, 49); + `CHECK_VAL(unpack_struct_array[1][0][0].val, 50); + `CHECK_VAL(unpack_struct_array[2][0][0].val, 51); + `CHECK_VAL(unpack_struct_array[3][0][0].val, 52); +`endif + + check_exports(); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_arg_inout_unpack__Dpi.out b/test_regress/t/t_dpi_arg_inout_unpack__Dpi.out new file mode 100644 index 000000000..c525fa429 --- /dev/null +++ b/test_regress/t/t_dpi_arg_inout_unpack__Dpi.out @@ -0,0 +1,313 @@ +// Verilated -*- C++ -*- +// DESCRIPTION: Verilator output: Prototypes for DPI import and export functions. +// +// Verilator includes this file in all generated .cpp files that use DPI functions. +// Manually include this file where DPI .c import functions are declared to ensure +// the C functions match the expectations of the DPI imports. + +#include "svdpi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + // DPI EXPORTS + // DPI export at t/t_dpi_arg_inout_unpack.v:529:18 + extern void e_bit121_0d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:530:18 + extern void e_bit121_1d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:531:18 + extern void e_bit121_2d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:532:18 + extern void e_bit121_3d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:524:18 + extern void e_bit7_0d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:525:18 + extern void e_bit7_1d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:526:18 + extern void e_bit7_2d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:527:18 + extern void e_bit7_3d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:395:18 + extern void e_byte_0d(char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:396:18 + extern void e_byte_1d(char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:397:18 + extern void e_byte_2d(char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:398:18 + extern void e_byte_3d(char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:400:18 + extern void e_byte_unsigned_0d(unsigned char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:401:18 + extern void e_byte_unsigned_1d(unsigned char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:402:18 + extern void e_byte_unsigned_2d(unsigned char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:403:18 + extern void e_byte_unsigned_3d(unsigned char* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:465:18 + extern void e_chandle_0d(void** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:469:18 + extern void e_chandle_1d(void** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:475:18 + extern void e_chandle_2d(void** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:483:18 + extern void e_chandle_3d(void** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:416:18 + extern void e_int_0d(int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:417:18 + extern void e_int_1d(int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:418:18 + extern void e_int_2d(int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:419:18 + extern void e_int_3d(int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:421:18 + extern void e_int_unsigned_0d(unsigned int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:422:18 + extern void e_int_unsigned_1d(unsigned int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:423:18 + extern void e_int_unsigned_2d(unsigned int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:424:18 + extern void e_int_unsigned_3d(unsigned int* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:446:18 + extern void e_integer_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:447:18 + extern void e_integer_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:448:18 + extern void e_integer_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:449:18 + extern void e_integer_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:539:18 + extern void e_logic121_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:540:18 + extern void e_logic121_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:541:18 + extern void e_logic121_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:542:18 + extern void e_logic121_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:534:18 + extern void e_logic7_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:535:18 + extern void e_logic7_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:536:18 + extern void e_logic7_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:537:18 + extern void e_logic7_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:428:18 + extern void e_longint_0d(long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:429:18 + extern void e_longint_1d(long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:430:18 + extern void e_longint_2d(long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:431:18 + extern void e_longint_3d(long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:433:18 + extern void e_longint_unsigned_0d(unsigned long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:434:18 + extern void e_longint_unsigned_1d(unsigned long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:435:18 + extern void e_longint_unsigned_2d(unsigned long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:436:18 + extern void e_longint_unsigned_3d(unsigned long long* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:544:18 + extern void e_pack_struct_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:545:18 + extern void e_pack_struct_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:546:18 + extern void e_pack_struct_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:547:18 + extern void e_pack_struct_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:452:18 + extern void e_real_0d(double* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:453:18 + extern void e_real_1d(double* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:454:18 + extern void e_real_2d(double* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:455:18 + extern void e_real_3d(double* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:405:18 + extern void e_shortint_0d(short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:406:18 + extern void e_shortint_1d(short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:407:18 + extern void e_shortint_2d(short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:408:18 + extern void e_shortint_3d(short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:410:18 + extern void e_shortint_unsigned_0d(unsigned short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:411:18 + extern void e_shortint_unsigned_1d(unsigned short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:412:18 + extern void e_shortint_unsigned_2d(unsigned short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:413:18 + extern void e_shortint_unsigned_3d(unsigned short* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:495:18 + extern void e_string_0d(const char** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:499:18 + extern void e_string_1d(const char** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:505:18 + extern void e_string_2d(const char** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:513:18 + extern void e_string_3d(const char** val); + // DPI export at t/t_dpi_arg_inout_unpack.v:439:18 + extern void e_time_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:440:18 + extern void e_time_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:441:18 + extern void e_time_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_inout_unpack.v:442:18 + extern void e_time_3d(svLogicVecVal* val); + + // DPI IMPORTS + // DPI import at t/t_dpi_arg_inout_unpack.v:584:41 + extern void check_exports(); + // DPI import at t/t_dpi_arg_inout_unpack.v:171:36 + extern void* get_non_null(); + // DPI import at t/t_dpi_arg_inout_unpack.v:254:33 + extern void i_bit121_0d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:255:33 + extern void i_bit121_1d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:256:33 + extern void i_bit121_2d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:257:33 + extern void i_bit121_3d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:249:33 + extern void i_bit7_0d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:250:33 + extern void i_bit7_1d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:251:33 + extern void i_bit7_2d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:252:33 + extern void i_bit7_3d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:173:33 + extern void i_byte_0d(char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:174:33 + extern void i_byte_1d(char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:175:33 + extern void i_byte_2d(char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:176:33 + extern void i_byte_3d(char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:178:33 + extern void i_byte_unsigned_0d(unsigned char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:179:33 + extern void i_byte_unsigned_1d(unsigned char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:180:33 + extern void i_byte_unsigned_2d(unsigned char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:181:33 + extern void i_byte_unsigned_3d(unsigned char* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:239:33 + extern void i_chandle_0d(void** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:240:33 + extern void i_chandle_1d(void** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:241:33 + extern void i_chandle_2d(void** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:242:33 + extern void i_chandle_3d(void** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:193:33 + extern void i_int_0d(int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:194:33 + extern void i_int_1d(int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:195:33 + extern void i_int_2d(int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:196:33 + extern void i_int_3d(int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:198:33 + extern void i_int_unsigned_0d(unsigned int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:199:33 + extern void i_int_unsigned_1d(unsigned int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:200:33 + extern void i_int_unsigned_2d(unsigned int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:201:33 + extern void i_int_unsigned_3d(unsigned int* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:221:33 + extern void i_integer_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:222:33 + extern void i_integer_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:223:33 + extern void i_integer_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:224:33 + extern void i_integer_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:264:33 + extern void i_logic121_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:265:33 + extern void i_logic121_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:266:33 + extern void i_logic121_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:267:33 + extern void i_logic121_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:259:33 + extern void i_logic7_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:260:33 + extern void i_logic7_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:261:33 + extern void i_logic7_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:262:33 + extern void i_logic7_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:203:33 + extern void i_longint_0d(long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:204:33 + extern void i_longint_1d(long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:205:33 + extern void i_longint_2d(long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:206:33 + extern void i_longint_3d(long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:208:33 + extern void i_longint_unsigned_0d(unsigned long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:209:33 + extern void i_longint_unsigned_1d(unsigned long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:210:33 + extern void i_longint_unsigned_2d(unsigned long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:211:33 + extern void i_longint_unsigned_3d(unsigned long long* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:269:33 + extern void i_pack_struct_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:270:33 + extern void i_pack_struct_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:271:33 + extern void i_pack_struct_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:272:33 + extern void i_pack_struct_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:227:33 + extern void i_real_0d(double* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:228:33 + extern void i_real_1d(double* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:229:33 + extern void i_real_2d(double* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:230:33 + extern void i_real_3d(double* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:183:33 + extern void i_shortint_0d(short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:184:33 + extern void i_shortint_1d(short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:185:33 + extern void i_shortint_2d(short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:186:33 + extern void i_shortint_3d(short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:188:33 + extern void i_shortint_unsigned_0d(unsigned short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:189:33 + extern void i_shortint_unsigned_1d(unsigned short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:190:33 + extern void i_shortint_unsigned_2d(unsigned short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:191:33 + extern void i_shortint_unsigned_3d(unsigned short* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:244:33 + extern void i_string_0d(const char** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:245:33 + extern void i_string_1d(const char** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:246:33 + extern void i_string_2d(const char** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:247:33 + extern void i_string_3d(const char** val); + // DPI import at t/t_dpi_arg_inout_unpack.v:214:33 + extern void i_time_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:215:33 + extern void i_time_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:216:33 + extern void i_time_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_inout_unpack.v:217:33 + extern void i_time_3d(svLogicVecVal* val); + +#ifdef __cplusplus +} +#endif diff --git a/test_regress/t/t_dpi_arg_input_unpack.cpp b/test_regress/t/t_dpi_arg_input_unpack.cpp new file mode 100644 index 000000000..695cedc6c --- /dev/null +++ b/test_regress/t/t_dpi_arg_input_unpack.cpp @@ -0,0 +1,778 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include +#include +#include +#include +#include + +// clang-format off +#if defined(NCSC) +// Used by NC's svdpi.h to pick up svLogicVecVal with _.aval and _.bval fields, +// rather than the IEEE 1800-2005 version which has _.a and _.b fields. +# define DPI_COMPATIBILITY_VERSION_1800v2012 +#endif + +#include "svdpi.h" + +#if defined(VERILATOR) // Verilator +# include "Vt_dpi_arg_input_unpack__Dpi.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +typedef const void** sv_chandle_array_ptr_t; +# define NO_SHORTREAL +# define NO_UNPACK_STRUCT +# define CONSTARG const +#elif defined(VCS) // VCS +# include "../vc_hdrs.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +typedef void** sv_chandle_array_ptr_t; +# define NO_TIME +# define CONSTARG const +#elif defined(NCSC) // NC +# include "dpi-exp.h" +# include "dpi-imp.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +typedef void** sv_chandle_array_ptr_t; +# define NO_TIME +# define NO_INTEGER +# define NO_SHORTREAL +// Sadly NC does not declare pass-by reference input arguments as const +# define CONSTARG +#elif defined(MS) // ModelSim +# include "dpi.h" +typedef int64_t sv_longint_t; +typedef uint64_t sv_longint_unsigned_t; +typedef const void** sv_chandle_array_ptr_t; +# define CONSTARG const +#else +# error "Unknown simulator for DPI test" +#endif +// clang-format on + +//====================================================================== +// Implementations of imported functions +//====================================================================== + +namespace { // unnamed namespace + +const bool VERBOSE_MESSAGE = false; + +#define stop() \ + do { \ + printf(__FILE__ ":%d Bad value\n", __LINE__); \ + abort(); \ + } while (0) + +template bool compare(const T& act, const T& exp) { + if (exp == act) { + if (VERBOSE_MESSAGE) { std::cout << "OK Exp:" << exp << " actual:" << act << std::endl; } + return true; + } else { + std::cout << "NG Exp:" << exp << " actual:" << act << std::endl; + return false; + } +} + +bool compare(const svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselLogic(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +bool compare(const svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselBit(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +template bool check_0d(T v) { return compare(v, 42); } +template bool check_1d(const T* v) { + return compare(v[0], 43) && compare(v[1], 44); +} +template bool check_2d(const T* v) { + return compare(v[0 * 2 + 1], 45) && compare(v[1 * 2 + 1], 46) + && compare(v[2 * 2 + 1], 47); +} +template bool check_3d(const T* v) { + return compare(v[(0 * 3 + 0) * 2 + 0], 48) && compare(v[(1 * 3 + 0) * 2 + 0], 49) + && compare(v[(2 * 3 + 0) * 2 + 0], 50) && compare(v[(3 * 3 + 0) * 2 + 0], 51); +} + +bool check_0d(const svLogicVecVal* v, int bitwidth) { return compare(v, 42, bitwidth); } +bool check_1d(const svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * 0, 43, bitwidth) && compare(v + unit * 1, 44, bitwidth); +} +bool check_2d(const svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * (0 * 2 + 1), 45, bitwidth) + && compare(v + unit * (1 * 2 + 1), 46, bitwidth) + && compare(v + unit * (2 * 2 + 1), 47, bitwidth); +} +bool check_3d(const svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * ((0 * 3 + 0) * 2 + 0), 48, bitwidth) + && compare(v + unit * ((1 * 3 + 0) * 2 + 0), 49, bitwidth) + && compare(v + unit * ((2 * 3 + 0) * 2 + 0), 50, bitwidth) + && compare(v + unit * ((3 * 3 + 0) * 2 + 0), 51, bitwidth); +} + +bool check_0d(const svBitVecVal* v, int bitwidth) { return compare(v, 42, bitwidth); } +bool check_1d(const svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * 0, 43, bitwidth) && compare(v + unit * 1, 44, bitwidth); +} +bool check_2d(const svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * (0 * 2 + 1), 45, bitwidth) + && compare(v + unit * (1 * 2 + 1), 46, bitwidth) + && compare(v + unit * (2 * 2 + 1), 47, bitwidth); +} +bool check_3d(const svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + return compare(v + unit * ((0 * 3 + 0) * 2 + 0), 48, bitwidth) + && compare(v + unit * ((1 * 3 + 0) * 2 + 0), 49, bitwidth) + && compare(v + unit * ((2 * 3 + 0) * 2 + 0), 50, bitwidth) + && compare(v + unit * ((3 * 3 + 0) * 2 + 0), 51, bitwidth); +} + +bool check_0d(const char* v) { return compare(v, "42"); } +bool check_1d(const char** v) { + return compare(v[0], "43") && compare(v[1], "44"); +} +bool check_2d(const char** v) { + return compare(v[0 * 2 + 1], "45") && compare(v[1 * 2 + 1], "46") + && compare(v[2 * 2 + 1], "47"); +} +bool check_3d(const char** v) { + return compare(v[(0 * 3 + 0) * 2 + 0], "48") + && compare(v[(1 * 3 + 0) * 2 + 0], "49") + && compare(v[(2 * 3 + 0) * 2 + 0], "50") + && compare(v[(3 * 3 + 0) * 2 + 0], "51"); +} + +template void set_values(T (&v)[4][3][2]) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) v[i][j][k] = 0; + v[3][2][1] = 42; + v[2][1][0] = 43; + v[2][1][1] = 44; + v[1][0][1] = 45; + v[1][1][1] = 46; + v[1][2][1] = 47; + v[0][0][0] = 48; + v[1][0][0] = 49; + v[2][0][0] = 50; + v[3][0][0] = 51; +} + +void set_uint(svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselLogic(v0, i, (val >> i) & 1); + else + svPutBitselLogic(v0, i, 0); + } +} + +void set_uint(svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselBit(v0, i, (val >> i) & 1); + else + svPutBitselBit(v0, i, 0); + } +} + +template void set_values(svLogicVecVal (&v)[4][3][2][N], int bitwidth) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) set_uint(v[i][j][k], 0, bitwidth); + set_uint(v[3][2][1], 42, bitwidth); + + set_uint(v[2][1][0], 43, bitwidth); + set_uint(v[2][1][1], 44, bitwidth); + + set_uint(v[1][0][1], 45, bitwidth); + set_uint(v[1][1][1], 46, bitwidth); + set_uint(v[1][2][1], 47, bitwidth); + + set_uint(v[0][0][0], 48, bitwidth); + set_uint(v[1][0][0], 49, bitwidth); + set_uint(v[2][0][0], 50, bitwidth); + set_uint(v[3][0][0], 51, bitwidth); +} + +template void set_values(svBitVecVal (&v)[4][3][2][N], int bitwidth) { + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) set_uint(v[i][j][k], 0, bitwidth); + set_uint(v[3][2][1], 42, bitwidth); + + set_uint(v[2][1][0], 43, bitwidth); + set_uint(v[2][1][1], 44, bitwidth); + + set_uint(v[1][0][1], 45, bitwidth); + set_uint(v[1][1][1], 46, bitwidth); + set_uint(v[1][2][1], 47, bitwidth); + + set_uint(v[0][0][0], 48, bitwidth); + set_uint(v[1][0][0], 49, bitwidth); + set_uint(v[2][0][0], 50, bitwidth); + set_uint(v[3][0][0], 51, bitwidth); +} + +sv_chandle_array_ptr_t add_const(void** ptr) { + return static_cast(static_cast(ptr)); +} + +} // unnamed namespace + +void* get_non_null() { + static int v; + return &v; +} + +void i_byte_0d(char v) { + if (!check_0d(v)) stop(); +} +void i_byte_1d(const char* v) { + if (!check_1d(v)) stop(); +} +void i_byte_2d(const char* v) { + if (!check_2d(v)) stop(); +} +void i_byte_3d(const char* v) { + if (!check_3d(v)) stop(); +} + +void i_byte_unsigned_0d(unsigned char v) { + if (!check_0d(v)) stop(); +} +void i_byte_unsigned_1d(const unsigned char* v) { + if (!check_1d(v)) stop(); +} +void i_byte_unsigned_2d(const unsigned char* v) { + if (!check_2d(v)) stop(); +} +void i_byte_unsigned_3d(const unsigned char* v) { + if (!check_3d(v)) stop(); +} + +void i_shortint_0d(short v) { + if (!check_0d(v)) stop(); +} +void i_shortint_1d(const short* v) { + if (!check_1d(v)) stop(); +} +void i_shortint_2d(const short* v) { + if (!check_2d(v)) stop(); +} +void i_shortint_3d(const short* v) { + if (!check_3d(v)) stop(); +} + +void i_shortint_unsigned_0d(unsigned short v) { + if (!check_0d(v)) stop(); +} +void i_shortint_unsigned_1d(const unsigned short* v) { + if (!check_1d(v)) stop(); +} +void i_shortint_unsigned_2d(const unsigned short* v) { + if (!check_2d(v)) stop(); +} +void i_shortint_unsigned_3d(const unsigned short* v) { + if (!check_3d(v)) stop(); +} + +void i_int_0d(int v) { + if (!check_0d(v)) stop(); +} +void i_int_1d(const int* v) { + if (!check_1d(v)) stop(); +} +void i_int_2d(const int* v) { + if (!check_2d(v)) stop(); +} +void i_int_3d(const int* v) { + if (!check_3d(v)) stop(); +} + +void i_int_unsigned_0d(unsigned v) { + if (!check_0d(v)) stop(); +} +void i_int_unsigned_1d(const unsigned* v) { + if (!check_1d(v)) stop(); +} +void i_int_unsigned_2d(const unsigned* v) { + if (!check_2d(v)) stop(); +} +void i_int_unsigned_3d(const unsigned* v) { + if (!check_3d(v)) stop(); +} + +void i_longint_0d(sv_longint_t v) { + if (!check_0d(v)) stop(); +} +void i_longint_1d(const sv_longint_t* v) { + if (!check_1d(v)) stop(); +} +void i_longint_2d(const sv_longint_t* v) { + if (!check_2d(v)) stop(); +} +void i_longint_3d(const sv_longint_t* v) { + if (!check_3d(v)) stop(); +} + +void i_longint_unsigned_0d(sv_longint_unsigned_t v) { + if (!check_0d(v)) stop(); +} +void i_longint_unsigned_1d(const sv_longint_unsigned_t* v) { + if (!check_1d(v)) stop(); +} +void i_longint_unsigned_2d(const sv_longint_unsigned_t* v) { + if (!check_2d(v)) stop(); +} +void i_longint_unsigned_3d(const sv_longint_unsigned_t* v) { + if (!check_3d(v)) stop(); +} + +#ifndef NO_TIME +void i_time_0d(CONSTARG svLogicVecVal* v) { + if (!check_0d(v, 64)) stop(); +} +void i_time_1d(CONSTARG svLogicVecVal* v) { + if (!check_1d(v, 64)) stop(); +} +void i_time_2d(CONSTARG svLogicVecVal* v) { + if (!check_2d(v, 64)) stop(); +} +void i_time_3d(CONSTARG svLogicVecVal* v) { + if (!check_3d(v, 64)) stop(); +} +#endif + +#ifndef NO_INTEGER +void i_integer_0d(CONSTARG svLogicVecVal* v) { + if (!check_0d(v, 32)) stop(); +} +void i_integer_1d(CONSTARG svLogicVecVal* v) { + if (!check_1d(v, 32)) stop(); +} +void i_integer_2d(CONSTARG svLogicVecVal* v) { + if (!check_2d(v, 32)) stop(); +} +void i_integer_3d(CONSTARG svLogicVecVal* v) { + if (!check_3d(v, 32)) stop(); +} +#endif + +void i_real_0d(double v) { + if (!check_0d(v)) stop(); +} +void i_real_1d(CONSTARG double* v) { + if (!check_1d(v)) stop(); +} +void i_real_2d(CONSTARG double* v) { + if (!check_2d(v)) stop(); +} +void i_real_3d(CONSTARG double* v) { + if (!check_3d(v)) stop(); +} + +#ifndef NO_SHORTREAL +void i_shortreal_0d(float v) { + if (!check_0d(v)) stop(); +} +void i_shortreal_1d(CONSTARG float* v) { + if (!check_1d(v)) stop(); +} +void i_shortreal_2d(CONSTARG float* v) { + if (!check_2d(v)) stop(); +} +void i_shortreal_3d(CONSTARG float* v) { + if (!check_3d(v)) stop(); +} +#endif + +void i_chandle_0d(void* v) { + if (!v) stop(); +} +void i_chandle_1d(sv_chandle_array_ptr_t v) { + if (!v[0]) stop(); + if (!v[1]) stop(); +} +void i_chandle_2d(sv_chandle_array_ptr_t v) { + if (!v[2 * 0 + 1]) stop(); + if (!v[2 * 1 + 1]) stop(); + if (!v[2 * 2 + 1]) stop(); +} +void i_chandle_3d(sv_chandle_array_ptr_t v) { + if (!v[(0 * 3 + 0) * 2 + 0]) stop(); + if (!v[(1 * 3 + 0) * 2 + 0]) stop(); + if (!v[(2 * 3 + 0) * 2 + 0]) stop(); + if (!v[(3 * 3 + 0) * 2 + 0]) stop(); +} + +void i_string_0d(CONSTARG char* v) { + if (!check_0d(v)) stop(); +} +void i_string_1d(CONSTARG char** v) { + if (!check_1d(v)) stop(); +} +void i_string_2d(CONSTARG char** v) { + if (!check_2d(v)) stop(); +} +void i_string_3d(CONSTARG char** v) { + if (!check_3d(v)) stop(); +} + +void i_bit7_0d(CONSTARG svBitVecVal* v) { + if (!check_0d(v, 7)) stop(); +} +void i_bit7_1d(CONSTARG svBitVecVal* v) { + if (!check_1d(v, 7)) stop(); +} +void i_bit7_2d(CONSTARG svBitVecVal* v) { + if (!check_2d(v, 7)) stop(); +} +void i_bit7_3d(CONSTARG svBitVecVal* v) { + if (!check_3d(v, 7)) stop(); +} + +void i_bit121_0d(CONSTARG svBitVecVal* v) { + if (!check_0d(v, 121)) stop(); +} +void i_bit121_1d(CONSTARG svBitVecVal* v) { + if (!check_1d(v, 121)) stop(); +} +void i_bit121_2d(CONSTARG svBitVecVal* v) { + if (!check_2d(v, 121)) stop(); +} +void i_bit121_3d(CONSTARG svBitVecVal* v) { + if (!check_3d(v, 121)) stop(); +} + +void i_logic7_0d(CONSTARG svLogicVecVal* v) { + if (!check_0d(v, 7)) stop(); +} +void i_logic7_1d(CONSTARG svLogicVecVal* v) { + if (!check_1d(v, 7)) stop(); +} +void i_logic7_2d(CONSTARG svLogicVecVal* v) { + if (!check_2d(v, 7)) stop(); +} +void i_logic7_3d(CONSTARG svLogicVecVal* v) { + if (!check_3d(v, 7)) stop(); +} + +void i_logic121_0d(CONSTARG svLogicVecVal* v) { + if (!check_0d(v, 121)) stop(); +} +void i_logic121_1d(CONSTARG svLogicVecVal* v) { + if (!check_1d(v, 121)) stop(); +} +void i_logic121_2d(CONSTARG svLogicVecVal* v) { + if (!check_2d(v, 121)) stop(); +} +void i_logic121_3d(CONSTARG svLogicVecVal* v) { + if (!check_3d(v, 121)) stop(); +} + +void i_pack_struct_0d(CONSTARG svLogicVecVal* v) { + if (!check_0d(v, 7)) stop(); +} +void i_pack_struct_1d(CONSTARG svLogicVecVal* v) { + if (!check_1d(v, 7)) stop(); +} +void i_pack_struct_2d(CONSTARG svLogicVecVal* v) { + if (!check_2d(v, 7)) stop(); +} +void i_pack_struct_3d(CONSTARG svLogicVecVal* v) { + if (!check_3d(v, 7)) stop(); +} + +#ifndef NO_UNPACK_STRUCT +void i_unpack_struct_0d(CONSTARG unpack_struct_t* v) { + if (!compare(v->val, 42, 121)) stop(); +} +void i_unpack_struct_1d(CONSTARG unpack_struct_t* v) { + if (!compare(v[0].val, 43, 121)) stop(); + if (!compare(v[1].val, 44, 121)) stop(); +} +void i_unpack_struct_2d(CONSTARG unpack_struct_t* v) { + if (!compare(v[0 * 2 + 1].val, 45, 121)) stop(); + if (!compare(v[1 * 2 + 1].val, 46, 121)) stop(); + if (!compare(v[2 * 2 + 1].val, 47, 121)) stop(); +} +void i_unpack_struct_3d(CONSTARG unpack_struct_t* v) { + if (!compare(v[(0 * 3 + 0) * 2 + 0].val, 48, 121)) stop(); + if (!compare(v[(1 * 3 + 0) * 2 + 0].val, 49, 121)) stop(); + if (!compare(v[(2 * 3 + 0) * 2 + 0].val, 50, 121)) stop(); + if (!compare(v[(3 * 3 + 0) * 2 + 0].val, 51, 121)) stop(); +} +#endif + +void check_exports() { + { + char byte_array[4][3][2]; + set_values(byte_array); + e_byte_0d(byte_array[3][2][1]); + e_byte_1d(&byte_array[2][1][0]); + e_byte_2d(&byte_array[1][0][0]); + e_byte_3d(&byte_array[0][0][0]); + } + { + unsigned char byte_unsigned_array[4][3][2]; + set_values(byte_unsigned_array); + e_byte_unsigned_0d(byte_unsigned_array[3][2][1]); + e_byte_unsigned_1d(&byte_unsigned_array[2][1][0]); + e_byte_unsigned_2d(&byte_unsigned_array[1][0][0]); + e_byte_unsigned_3d(&byte_unsigned_array[0][0][0]); + } + { + short shortint_array[4][3][2]; + set_values(shortint_array); + e_shortint_0d(shortint_array[3][2][1]); + e_shortint_1d(&shortint_array[2][1][0]); + e_shortint_2d(&shortint_array[1][0][0]); + e_shortint_3d(&shortint_array[0][0][0]); + } + { + unsigned short shortint_unsigned_array[4][3][2]; + set_values(shortint_unsigned_array); + e_shortint_unsigned_0d(shortint_unsigned_array[3][2][1]); + e_shortint_unsigned_1d(&shortint_unsigned_array[2][1][0]); + e_shortint_unsigned_2d(&shortint_unsigned_array[1][0][0]); + e_shortint_unsigned_3d(&shortint_unsigned_array[0][0][0]); + } + { + int int_array[4][3][2]; + set_values(int_array); + e_int_0d(int_array[3][2][1]); + e_int_1d(&int_array[2][1][0]); + e_int_2d(&int_array[1][0][0]); + e_int_3d(&int_array[0][0][0]); + } + { + unsigned int int_unsigned_array[4][3][2]; + set_values(int_unsigned_array); + e_int_unsigned_0d(int_unsigned_array[3][2][1]); + e_int_unsigned_1d(&int_unsigned_array[2][1][0]); + e_int_unsigned_2d(&int_unsigned_array[1][0][0]); + e_int_unsigned_3d(&int_unsigned_array[0][0][0]); + } + { + sv_longint_t longint_array[4][3][2]; + set_values(longint_array); + e_longint_0d(longint_array[3][2][1]); + e_longint_1d(&longint_array[2][1][0]); + e_longint_2d(&longint_array[1][0][0]); + e_longint_3d(&longint_array[0][0][0]); + } + { + sv_longint_unsigned_t longint_unsigned_array[4][3][2]; + set_values(longint_unsigned_array); + e_longint_unsigned_0d(longint_unsigned_array[3][2][1]); + e_longint_unsigned_1d(&longint_unsigned_array[2][1][0]); + e_longint_unsigned_2d(&longint_unsigned_array[1][0][0]); + e_longint_unsigned_3d(&longint_unsigned_array[0][0][0]); + } +#ifndef NO_TIME + { + svLogicVecVal time_array[4][3][2][2]; + set_values(time_array, 64); + e_time_0d(time_array[3][2][1]); + e_time_1d(time_array[2][1][0]); + e_time_2d(&time_array[1][0][0][0]); + e_time_3d(time_array[0][0][0]); + } +#endif + +#ifndef NO_INTEGER + { + svLogicVecVal integer_array[4][3][2][1]; + set_values(integer_array, 32); + e_integer_0d(integer_array[3][2][1]); + e_integer_1d(integer_array[2][1][0]); + e_integer_2d(&integer_array[1][0][0][0]); + e_integer_3d(integer_array[0][0][0]); + } +#endif + + { + double real_array[4][3][2]; + set_values(real_array); + e_real_0d(real_array[3][2][1]); + e_real_1d(&real_array[2][1][0]); + e_real_2d(&real_array[1][0][0]); + e_real_3d(&real_array[0][0][0]); + } +#ifndef NO_SHORTREAL + { + float shortreal_array[4][3][2]; + set_values(shortreal_array); + e_shortreal_0d(shortreal_array[3][2][1]); + e_shortreal_1d(&shortreal_array[2][1][0]); + e_shortreal_2d(&shortreal_array[1][0][0]); + e_shortreal_3d(&shortreal_array[0][0][0]); + } +#endif + + { + void* chandle_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) chandle_array[i][j][k] = NULL; + chandle_array[3][2][1] = get_non_null(); + chandle_array[2][1][0] = get_non_null(); + chandle_array[2][1][1] = get_non_null(); + + chandle_array[1][0][1] = get_non_null(); + chandle_array[1][1][1] = get_non_null(); + chandle_array[1][2][1] = get_non_null(); + + chandle_array[0][0][0] = get_non_null(); + chandle_array[1][0][0] = get_non_null(); + chandle_array[2][0][0] = get_non_null(); + chandle_array[3][0][0] = get_non_null(); + + e_chandle_0d(chandle_array[3][2][1]); + e_chandle_1d(add_const(&chandle_array[2][1][0])); + e_chandle_2d(add_const(&chandle_array[1][0][0])); + e_chandle_3d(add_const(&chandle_array[0][0][0])); + } + + { + std::vector buf; + buf.resize(4 * 3 * 2 * 16, '\0'); + buf[((3 * 3 + 2) * 2 + 1) * 16 + 0] = '4'; + buf[((3 * 3 + 2) * 2 + 1) * 16 + 1] = '2'; + buf[((2 * 3 + 1) * 2 + 0) * 16 + 0] = '4'; + buf[((2 * 3 + 1) * 2 + 0) * 16 + 1] = '3'; + buf[((2 * 3 + 1) * 2 + 1) * 16 + 0] = '4'; + buf[((2 * 3 + 1) * 2 + 1) * 16 + 1] = '4'; + buf[((1 * 3 + 0) * 2 + 1) * 16 + 0] = '4'; + buf[((1 * 3 + 0) * 2 + 1) * 16 + 1] = '5'; + buf[((1 * 3 + 1) * 2 + 1) * 16 + 0] = '4'; + buf[((1 * 3 + 1) * 2 + 1) * 16 + 1] = '6'; + buf[((1 * 3 + 2) * 2 + 1) * 16 + 0] = '4'; + buf[((1 * 3 + 2) * 2 + 1) * 16 + 1] = '7'; + buf[((0 * 3 + 0) * 2 + 0) * 16 + 0] = '4'; + buf[((0 * 3 + 0) * 2 + 0) * 16 + 1] = '8'; + buf[((1 * 3 + 0) * 2 + 0) * 16 + 0] = '4'; + buf[((1 * 3 + 0) * 2 + 0) * 16 + 1] = '9'; + buf[((2 * 3 + 0) * 2 + 0) * 16 + 0] = '5'; + buf[((2 * 3 + 0) * 2 + 0) * 16 + 1] = '0'; + buf[((3 * 3 + 0) * 2 + 0) * 16 + 0] = '5'; + buf[((3 * 3 + 0) * 2 + 0) * 16 + 1] = '1'; + const char* string_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) + string_array[i][j][k] = buf.data() + ((i * 3 + j) * 2 + k) * 16; + e_string_0d(string_array[3][2][1]); + e_string_1d(&string_array[2][1][0]); + e_string_2d(&string_array[1][0][0]); + e_string_3d(&string_array[0][0][0]); + } + + { + svBitVecVal bit7_array[4][3][2][1]; + set_values(bit7_array, 7); + e_bit7_0d(bit7_array[3][2][1]); + e_bit7_1d(bit7_array[2][1][0]); + e_bit7_2d(bit7_array[1][0][0]); + e_bit7_3d(bit7_array[0][0][0]); + } + + { + svBitVecVal bit121_array[4][3][2][4]; + set_values(bit121_array, 121); + e_bit121_0d(bit121_array[3][2][1]); + e_bit121_1d(bit121_array[2][1][0]); + e_bit121_2d(bit121_array[1][0][0]); + e_bit121_3d(bit121_array[0][0][0]); + } + + { + svLogicVecVal logic7_array[4][3][2][1]; + set_values(logic7_array, 7); + e_logic7_0d(logic7_array[3][2][1]); + e_logic7_1d(logic7_array[2][1][0]); + e_logic7_2d(logic7_array[1][0][0]); + e_logic7_3d(logic7_array[0][0][0]); + } + + { + svLogicVecVal logic121_array[4][3][2][4]; + set_values(logic121_array, 121); + e_logic121_0d(logic121_array[3][2][1]); + e_logic121_1d(logic121_array[2][1][0]); + e_logic121_2d(logic121_array[1][0][0]); + e_logic121_3d(logic121_array[0][0][0]); + } + + { + svLogicVecVal pack_struct_array[4][3][2][1]; + set_values(pack_struct_array, 7); + e_pack_struct_0d(pack_struct_array[3][2][1]); + e_pack_struct_1d(pack_struct_array[2][1][0]); + e_pack_struct_2d(pack_struct_array[1][0][0]); + e_pack_struct_3d(pack_struct_array[0][0][0]); + } + +#ifndef NO_UNPACK_STRUCT + { + unpack_struct_t unpack_struct_array[4][3][2]; + set_uint(unpack_struct_array[3][2][1].val, 42, 121); + + set_uint(unpack_struct_array[2][1][0].val, 43, 121); + set_uint(unpack_struct_array[2][1][1].val, 44, 121); + + set_uint(unpack_struct_array[1][0][1].val, 45, 121); + set_uint(unpack_struct_array[1][1][1].val, 46, 121); + set_uint(unpack_struct_array[1][2][1].val, 47, 121); + + set_uint(unpack_struct_array[0][0][0].val, 48, 121); + set_uint(unpack_struct_array[1][0][0].val, 49, 121); + set_uint(unpack_struct_array[2][0][0].val, 50, 121); + set_uint(unpack_struct_array[3][0][0].val, 51, 121); + e_unpack_struct_0d(&unpack_struct_array[3][2][1]); + e_unpack_struct_1d(&unpack_struct_array[2][1][0]); + e_unpack_struct_2d(&unpack_struct_array[1][0][0]); + e_unpack_struct_3d(&unpack_struct_array[0][0][0]); + } +#endif +} diff --git a/test_regress/t/t_dpi_arg_input_unpack.pl b/test_regress/t/t_dpi_arg_input_unpack.pl new file mode 100755 index 000000000..364897b82 --- /dev/null +++ b/test_regress/t/t_dpi_arg_input_unpack.pl @@ -0,0 +1,44 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +if ($Self->{nc}) { + # For NC, compile twice, first just to generate DPI headers + compile( + nc_flags2 => ["+ncdpiheader+$Self->{obj_dir}/dpi-exp.h", + "+ncdpiimpheader+$Self->{obj_dir}/dpi-imp.h"] + ); +} + +compile( + v_flags2 => ["t/t_dpi_arg_input_unpack.cpp"], + verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], + # NC: Gdd the obj_dir to the C include path + nc_flags2 => ["+ncscargs+-I$Self->{obj_dir}"], + # ModelSim: Generate DPI header, add obj_dir to the C include path + ms_flags2 => ["-dpiheader $Self->{obj_dir}/dpi.h", + "-ccflags -I$Self->{obj_dir}"], + ); + +if ($Self->{vlt_all}) { + files_identical( + "$Self->{obj_dir}/Vt_dpi_arg_input_unpack__Dpi.h", + "t/t_dpi_arg_input_unpack__Dpi.out" + ); +} + +execute( + check_finished => 1, + ms_pli => 0 + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_arg_input_unpack.v b/test_regress/t/t_dpi_arg_input_unpack.v new file mode 100644 index 000000000..0a698e905 --- /dev/null +++ b/test_regress/t/t_dpi_arg_input_unpack.v @@ -0,0 +1,770 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +`ifdef VCS + `define NO_TIME +`endif + +`ifdef NC + `define NO_TIME + `define NO_INTEGER + `define NO_SHORTREAL +`endif + +`ifdef MS +`endif + +`ifdef VERILATOR + `define NO_SHORTREAL + `define NO_UNPACK_STRUCT + `define NULL 64'd0 +`else + `define NULL null +`endif + +`define CHECK_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":", (act), " as expected"); \ + end else begin \ + $display("Mismatch %s expected:%d actual:%d at %d", `"act`", \ + int'(exp), int'(act), `__LINE__); \ + $stop; \ + end + +`define CHECK_0D(val) `CHECK_VAL((val), 42) +`define CHECK_1D(val) `CHECK_VAL(val[0], 43); \ +`CHECK_VAL(val[1], 44) +`define CHECK_2D(val) `CHECK_VAL(val[0][1], 45); \ +`CHECK_VAL(val[1][1], 46); \ +`CHECK_VAL(val[2][1], 47) +`define CHECK_3D(val) `CHECK_VAL(val[0][0][0], 48); \ +`CHECK_VAL(val[1][0][0], 49); \ +`CHECK_VAL(val[2][0][0], 50); \ +`CHECK_VAL(val[3][0][0], 51) + +`define SET_VALUES(val) \ +val[3][2][1] = 42; \ +val[2][1][0] = 43; val[2][1][1] = 44; \ +val[1][0][1] = 45; val[1][1][1] = 46; val[1][2][1] = 47; \ +val[0][0][0] = 48; val[1][0][0] = 49; val[2][0][0] = 50; val[3][0][0] = 51 + +module t; + + localparam ENABLE_VERBOSE_MESSAGE = 0; + + // Legal input argument types for DPI functions + + //====================================================================== + // Type definitions + //====================================================================== + + typedef byte byte_array_t[4][3][2]; + typedef byte unsigned byte_unsigned_array_t[4][3][2]; + typedef shortint shortint_array_t[4][3][2]; + typedef shortint unsigned shortint_unsigned_array_t[4][3][2]; + typedef int int_array_t[4][3][2]; + typedef int unsigned int_unsigned_array_t[4][3][2]; + typedef longint longint_array_t[4][3][2]; + typedef longint unsigned longint_unsigned_array_t[4][3][2]; +`ifndef NO_TIME + typedef time time_array_t[4][3][2]; +`endif +`ifndef NO_INTEGER + typedef integer integer_array_t[4][3][2]; +`endif + typedef real real_array_t[4][3][2]; +`ifndef NO_SHORTREAL + typedef shortreal shortreal_array_t[4][3][2]; +`endif + typedef chandle chandle_array_t[4][3][2]; + typedef string string_array_t[4][3][2]; + typedef bit [6:0] bit7_array_t[4][3][2]; + typedef bit [120:0] bit121_array_t[4][3][2]; + typedef logic [6:0] logic7_array_t[4][3][2]; + typedef logic [120:0] logic121_array_t[4][3][2]; + + typedef struct packed { + logic [6:0] val; + } pack_struct_t; + typedef pack_struct_t pack_struct_array_t[4][3][2]; +`ifndef NO_UNPACK_STRUCT + typedef struct { + logic [120:0] val; + } unpack_struct_t; + typedef unpack_struct_t unpack_struct_array_t[4][3][2]; +`endif + + //====================================================================== + // Imports + //====================================================================== + + // Returns non-null pointer + import "DPI-C" function chandle get_non_null(); + + import "DPI-C" function void i_byte_0d(input byte val); + import "DPI-C" function void i_byte_1d(input byte val[2]); + import "DPI-C" function void i_byte_2d(input byte val[3][2]); + import "DPI-C" function void i_byte_3d(input byte_array_t val); + + import "DPI-C" function void i_byte_unsigned_0d(input byte unsigned val); + import "DPI-C" function void i_byte_unsigned_1d(input byte unsigned val[2]); + import "DPI-C" function void i_byte_unsigned_2d(input byte unsigned val[3][2]); + import "DPI-C" function void i_byte_unsigned_3d(input byte_unsigned_array_t val); + + import "DPI-C" function void i_shortint_0d(input shortint val); + import "DPI-C" function void i_shortint_1d(input shortint val[2]); + import "DPI-C" function void i_shortint_2d(input shortint val[3][2]); + import "DPI-C" function void i_shortint_3d(input shortint_array_t val); + + import "DPI-C" function void i_shortint_unsigned_0d(input shortint unsigned val); + import "DPI-C" function void i_shortint_unsigned_1d(input shortint unsigned val[2]); + import "DPI-C" function void i_shortint_unsigned_2d(input shortint unsigned val[3][2]); + import "DPI-C" function void i_shortint_unsigned_3d(input shortint_unsigned_array_t val); + + import "DPI-C" function void i_int_0d(input int val); + import "DPI-C" function void i_int_1d(input int val[2]); + import "DPI-C" function void i_int_2d(input int val[3][2]); + import "DPI-C" function void i_int_3d(input int_array_t val); + + import "DPI-C" function void i_int_unsigned_0d(input int unsigned val); + import "DPI-C" function void i_int_unsigned_1d(input int unsigned val[2]); + import "DPI-C" function void i_int_unsigned_2d(input int unsigned val[3][2]); + import "DPI-C" function void i_int_unsigned_3d(input int_unsigned_array_t val); + + import "DPI-C" function void i_longint_0d(input longint val); + import "DPI-C" function void i_longint_1d(input longint val[2]); + import "DPI-C" function void i_longint_2d(input longint val[3][2]); + import "DPI-C" function void i_longint_3d(input longint_array_t val); + + import "DPI-C" function void i_longint_unsigned_0d(input longint unsigned val); + import "DPI-C" function void i_longint_unsigned_1d(input longint unsigned val[2]); + import "DPI-C" function void i_longint_unsigned_2d(input longint unsigned val[3][2]); + import "DPI-C" function void i_longint_unsigned_3d(input longint_unsigned_array_t val); + +`ifndef NO_TIME + import "DPI-C" function void i_time_0d(input time val); + import "DPI-C" function void i_time_1d(input time val[2]); + import "DPI-C" function void i_time_2d(input time val[3][2]); + import "DPI-C" function void i_time_3d(input time_array_t val); +`endif + +`ifndef NO_INTEGER + import "DPI-C" function void i_integer_0d(input integer val); + import "DPI-C" function void i_integer_1d(input integer val[2]); + import "DPI-C" function void i_integer_2d(input integer val[3][2]); + import "DPI-C" function void i_integer_3d(input integer_array_t val); +`endif + + import "DPI-C" function void i_real_0d(input real val); + import "DPI-C" function void i_real_1d(input real val[2]); + import "DPI-C" function void i_real_2d(input real val[3][2]); + import "DPI-C" function void i_real_3d(input real_array_t val); + +`ifndef NO_SHORTREAL + import "DPI-C" function void i_shortreal_0d(input shortreal val); + import "DPI-C" function void i_shortreal_1d(input shortreal val[2]); + import "DPI-C" function void i_shortreal_2d(input shortreal val[3][2]); + import "DPI-C" function void i_shortreal_3d(input shortreal_array_t val); +`endif + + import "DPI-C" function void i_chandle_0d(input chandle val); + import "DPI-C" function void i_chandle_1d(input chandle val[2]); + import "DPI-C" function void i_chandle_2d(input chandle val[3][2]); + import "DPI-C" function void i_chandle_3d(input chandle_array_t val); + + import "DPI-C" function void i_string_0d(input string val); + import "DPI-C" function void i_string_1d(input string val[2]); + import "DPI-C" function void i_string_2d(input string val[3][2]); + import "DPI-C" function void i_string_3d(input string_array_t val); + + import "DPI-C" function void i_bit7_0d(input bit[6:0] val); + import "DPI-C" function void i_bit7_1d(input bit[6:0] val[2]); + import "DPI-C" function void i_bit7_2d(input bit[6:0] val[3][2]); + import "DPI-C" function void i_bit7_3d(input bit7_array_t val); + + import "DPI-C" function void i_bit121_0d(input bit[120:0] val); + import "DPI-C" function void i_bit121_1d(input bit[120:0] val[2]); + import "DPI-C" function void i_bit121_2d(input bit[120:0] val[3][2]); + import "DPI-C" function void i_bit121_3d(input bit121_array_t val); + + import "DPI-C" function void i_logic7_0d(input logic[6:0] val); + import "DPI-C" function void i_logic7_1d(input logic[6:0] val[2]); + import "DPI-C" function void i_logic7_2d(input logic[6:0] val[3][2]); + import "DPI-C" function void i_logic7_3d(input logic7_array_t val); + + import "DPI-C" function void i_logic121_0d(input logic[120:0] val); + import "DPI-C" function void i_logic121_1d(input logic[120:0] val[2]); + import "DPI-C" function void i_logic121_2d(input logic[120:0] val[3][2]); + import "DPI-C" function void i_logic121_3d(input logic121_array_t val); + + import "DPI-C" function void i_pack_struct_0d(input pack_struct_t val); + import "DPI-C" function void i_pack_struct_1d(input pack_struct_t val[2]); + import "DPI-C" function void i_pack_struct_2d(input pack_struct_t val[3][2]); + import "DPI-C" function void i_pack_struct_3d(input pack_struct_array_t val); + +`ifndef NO_UNPACK_STRUCT + import "DPI-C" function void i_unpack_struct_0d(input unpack_struct_t val); + import "DPI-C" function void i_unpack_struct_1d(input unpack_struct_t val[2]); + import "DPI-C" function void i_unpack_struct_2d(input unpack_struct_t val[3][2]); + import "DPI-C" function void i_unpack_struct_3d(input unpack_struct_array_t val); +`endif + + + //====================================================================== + // Exports + //====================================================================== + + export "DPI-C" function e_byte_0d; + export "DPI-C" function e_byte_1d; + export "DPI-C" function e_byte_2d; + export "DPI-C" function e_byte_3d; + + export "DPI-C" function e_byte_unsigned_0d; + export "DPI-C" function e_byte_unsigned_1d; + export "DPI-C" function e_byte_unsigned_2d; + export "DPI-C" function e_byte_unsigned_3d; + + export "DPI-C" function e_shortint_0d; + export "DPI-C" function e_shortint_1d; + export "DPI-C" function e_shortint_2d; + export "DPI-C" function e_shortint_3d; + + export "DPI-C" function e_shortint_unsigned_0d; + export "DPI-C" function e_shortint_unsigned_1d; + export "DPI-C" function e_shortint_unsigned_2d; + export "DPI-C" function e_shortint_unsigned_3d; + + export "DPI-C" function e_int_0d; + export "DPI-C" function e_int_1d; + export "DPI-C" function e_int_2d; + export "DPI-C" function e_int_3d; + + export "DPI-C" function e_int_unsigned_0d; + export "DPI-C" function e_int_unsigned_1d; + export "DPI-C" function e_int_unsigned_2d; + export "DPI-C" function e_int_unsigned_3d; + + export "DPI-C" function e_longint_0d; + export "DPI-C" function e_longint_1d; + export "DPI-C" function e_longint_2d; + export "DPI-C" function e_longint_3d; + + export "DPI-C" function e_longint_unsigned_0d; + export "DPI-C" function e_longint_unsigned_1d; + export "DPI-C" function e_longint_unsigned_2d; + export "DPI-C" function e_longint_unsigned_3d; + +`ifndef NO_TIME + export "DPI-C" function e_time_0d; + export "DPI-C" function e_time_1d; + export "DPI-C" function e_time_2d; + export "DPI-C" function e_time_3d; +`endif + +`ifndef NO_INTEGER + export "DPI-C" function e_integer_0d; + export "DPI-C" function e_integer_1d; + export "DPI-C" function e_integer_2d; + export "DPI-C" function e_integer_3d; +`endif + + export "DPI-C" function e_real_0d; + export "DPI-C" function e_real_1d; + export "DPI-C" function e_real_2d; + export "DPI-C" function e_real_3d; + +`ifndef NO_SHORTREAL + export "DPI-C" function e_shortreal_0d; + export "DPI-C" function e_shortreal_1d; + export "DPI-C" function e_shortreal_2d; + export "DPI-C" function e_shortreal_3d; +`endif + + export "DPI-C" function e_chandle_0d; + export "DPI-C" function e_chandle_1d; + export "DPI-C" function e_chandle_2d; + export "DPI-C" function e_chandle_3d; + + export "DPI-C" function e_string_0d; + export "DPI-C" function e_string_1d; + export "DPI-C" function e_string_2d; + export "DPI-C" function e_string_3d; + + export "DPI-C" function e_bit7_0d; + export "DPI-C" function e_bit7_1d; + export "DPI-C" function e_bit7_2d; + export "DPI-C" function e_bit7_3d; + + export "DPI-C" function e_bit121_0d; + export "DPI-C" function e_bit121_1d; + export "DPI-C" function e_bit121_2d; + export "DPI-C" function e_bit121_3d; + + export "DPI-C" function e_logic7_0d; + export "DPI-C" function e_logic7_1d; + export "DPI-C" function e_logic7_2d; + export "DPI-C" function e_logic7_3d; + + export "DPI-C" function e_logic121_0d; + export "DPI-C" function e_logic121_1d; + export "DPI-C" function e_logic121_2d; + export "DPI-C" function e_logic121_3d; + + export "DPI-C" function e_pack_struct_0d; + export "DPI-C" function e_pack_struct_1d; + export "DPI-C" function e_pack_struct_2d; + export "DPI-C" function e_pack_struct_3d; + +`ifndef NO_UNPACK_STRUCT + export "DPI-C" function e_unpack_struct_0d; + export "DPI-C" function e_unpack_struct_1d; + export "DPI-C" function e_unpack_struct_2d; + export "DPI-C" function e_unpack_struct_3d; +`endif + + //====================================================================== + // Definitions of exported functions + //====================================================================== + function void e_byte_0d(input byte val); `CHECK_0D(val); endfunction + function void e_byte_1d(input byte val[2]); `CHECK_1D(val); endfunction + function void e_byte_2d(input byte val[3][2]); `CHECK_2D(val); endfunction + function void e_byte_3d(input byte_array_t val); `CHECK_3D(val); endfunction + + function void e_byte_unsigned_0d(input byte unsigned val); `CHECK_0D(val); endfunction + function void e_byte_unsigned_1d(input byte unsigned val[2]); `CHECK_1D(val); endfunction + function void e_byte_unsigned_2d(input byte unsigned val[3][2]); `CHECK_2D(val); endfunction + function void e_byte_unsigned_3d(input byte_unsigned_array_t val); `CHECK_3D(val); endfunction + + function void e_shortint_0d(input shortint val); `CHECK_0D(val); endfunction + function void e_shortint_1d(input shortint val[2]); `CHECK_1D(val); endfunction + function void e_shortint_2d(input shortint val[3][2]); `CHECK_2D(val); endfunction + function void e_shortint_3d(input shortint_array_t val); `CHECK_3D(val); endfunction + + function void e_shortint_unsigned_0d(input shortint unsigned val); `CHECK_0D(val); endfunction + function void e_shortint_unsigned_1d(input shortint unsigned val[2]); `CHECK_1D(val); endfunction + function void e_shortint_unsigned_2d(input shortint unsigned val[3][2]); `CHECK_2D(val); endfunction + function void e_shortint_unsigned_3d(input shortint_unsigned_array_t val); `CHECK_3D(val); endfunction + + function void e_int_0d(input int val); `CHECK_0D(val); endfunction + function void e_int_1d(input int val[2]); `CHECK_1D(val); endfunction + function void e_int_2d(input int val[3][2]); `CHECK_2D(val); endfunction + function void e_int_3d(input int_array_t val); `CHECK_3D(val); endfunction + + function void e_int_unsigned_0d(input int unsigned val); `CHECK_0D(val); endfunction + function void e_int_unsigned_1d(input int unsigned val[2]); `CHECK_1D(val); endfunction + function void e_int_unsigned_2d(input int unsigned val[3][2]); `CHECK_2D(val); endfunction + function void e_int_unsigned_3d(input int_unsigned_array_t val); `CHECK_3D(val); endfunction + + function void e_longint_0d(input longint val); `CHECK_0D(val); endfunction + function void e_longint_1d(input longint val[2]); `CHECK_1D(val); endfunction + function void e_longint_2d(input longint val[3][2]); `CHECK_2D(val); endfunction + function void e_longint_3d(input longint_array_t val); `CHECK_3D(val); endfunction + + function void e_longint_unsigned_0d(input longint unsigned val); `CHECK_0D(val); endfunction + function void e_longint_unsigned_1d(input longint unsigned val[2]); `CHECK_1D(val); endfunction + function void e_longint_unsigned_2d(input longint unsigned val[3][2]); `CHECK_2D(val); endfunction + function void e_longint_unsigned_3d(input longint_unsigned_array_t val); `CHECK_3D(val); endfunction + +`ifndef NO_TIME + function void e_time_0d(input time val); `CHECK_0D(val); endfunction + function void e_time_1d(input time val[2]); `CHECK_1D(val); endfunction + function void e_time_2d(input time val[3][2]); `CHECK_2D(val); endfunction + function void e_time_3d(input time_array_t val); `CHECK_3D(val); endfunction +`endif + +`ifndef NO_INTEGER + function void e_integer_0d(input integer val); `CHECK_0D(val); endfunction + function void e_integer_1d(input integer val[2]); `CHECK_1D(val); endfunction + function void e_integer_2d(input integer val[3][2]); `CHECK_2D(val); endfunction + function void e_integer_3d(input integer_array_t val); `CHECK_3D(val); endfunction +`endif + + function void e_real_0d(input real val); `CHECK_0D(val); endfunction + function void e_real_1d(input real val[2]); `CHECK_1D(val); endfunction + function void e_real_2d(input real val[3][2]); `CHECK_2D(val); endfunction + function void e_real_3d(input real_array_t val); `CHECK_3D(val); endfunction + +`ifndef NO_SHORTREAL + function void e_shortreal_0d(input shortreal val); `CHECK_0D(val); endfunction + function void e_shortreal_1d(input shortreal val[2]); `CHECK_1D(val); endfunction + function void e_shortreal_2d(input shortreal val[3][2]); `CHECK_2D(val); endfunction + function void e_shortreal_3d(input shortreal_array_t val); `CHECK_3D(val); endfunction +`endif + + function void e_chandle_0d(input chandle val); + if (val == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + endfunction + function void e_chandle_1d(input chandle val[2]); + if (val[0] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[1] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + endfunction + function void e_chandle_2d(input chandle val[3][2]); + if (val[0][1] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[1][1] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[2][1] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + endfunction + function void e_chandle_3d(input chandle_array_t val); + if (val[0][0][0] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[1][0][0] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[2][0][0] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + if (val[3][0][0] == null) begin + $display("Mismatch non null is expected, but not."); + $stop; + end + endfunction + + function void e_string_0d(input string val); + if (val != "42") begin + $display("Mismatch expected:%s actual:%s", "42", val); + $stop; + end + endfunction + function void e_string_1d(input string val[2]); + if (val[0] != "43") begin + $display("Mismatch expected:%s actual:%s", "43", val[0]); + $stop; + end + if (val[1] != "44") begin + $display("Mismatch expected:%s actual:%s", "44", val[1]); + $stop; + end + endfunction + function void e_string_2d(input string val[3][2]); + if (val[0][1] != "45") begin + $display("Mismatch expected:%s actual:%s", "45", val[0][1]); + $stop; + end + if (val[1][1] != "46") begin + $display("Mismatch expected:%s actual:%s", "46", val[1][1]); + $stop; + end + if (val[2][1] != "47") begin + $display("Mismatch expected:%s actual:%s", "47", val[2][1]); + $stop; + end + endfunction + function void e_string_3d(input string_array_t val); + if (val[0][0][0] != "48") begin + $display("Mismatch expected:%s actual:%s", "48", val[0][0][0]); + $stop; + end + if (val[1][0][0] != "49") begin + $display("Mismatch expected:%s actual:%s", "49", val[1][0][0]); + $stop; + end + if (val[2][0][0] != "50") begin + $display("Mismatch expected:%s actual:%s", "50", val[2][0][0]); + $stop; + end + if (val[3][0][0] != "51") begin + $display("Mismatch expected:%s actual:%s", "51", val[3][0][0]); + $stop; + end + endfunction + + function void e_bit7_0d(input bit[6:0] val); `CHECK_0D(val); endfunction + function void e_bit7_1d(input bit[6:0] val[2]); `CHECK_1D(val); endfunction + function void e_bit7_2d(input bit[6:0] val[3][2]); `CHECK_2D(val); endfunction + function void e_bit7_3d(input bit7_array_t val); `CHECK_3D(val); endfunction + + function void e_bit121_0d(input bit[120:0] val); `CHECK_0D(val); endfunction + function void e_bit121_1d(input bit[120:0] val[2]); `CHECK_1D(val); endfunction + function void e_bit121_2d(input bit[120:0] val[3][2]); `CHECK_2D(val); endfunction + function void e_bit121_3d(input bit121_array_t val); `CHECK_3D(val); endfunction + + function void e_logic7_0d(input logic[6:0] val); `CHECK_0D(val); endfunction + function void e_logic7_1d(input logic[6:0] val[2]); `CHECK_1D(val); endfunction + function void e_logic7_2d(input logic[6:0] val[3][2]); `CHECK_2D(val); endfunction + function void e_logic7_3d(input logic7_array_t val); `CHECK_3D(val); endfunction + + function void e_logic121_0d(input logic[120:0] val); `CHECK_0D(val); endfunction + function void e_logic121_1d(input logic[120:0] val[2]); `CHECK_1D(val); endfunction + function void e_logic121_2d(input logic[120:0] val[3][2]); `CHECK_2D(val); endfunction + function void e_logic121_3d(input logic121_array_t val); `CHECK_3D(val); endfunction + + function void e_pack_struct_0d(input pack_struct_t val); `CHECK_0D(val); endfunction + function void e_pack_struct_1d(input pack_struct_t val[2]); `CHECK_1D(val); endfunction + function void e_pack_struct_2d(input pack_struct_t val[3][2]); `CHECK_2D(val); endfunction + function void e_pack_struct_3d(input pack_struct_array_t val); `CHECK_3D(val); endfunction + +`ifndef NO_UNPACK_STRUCT + function void e_unpack_struct_0d(input unpack_struct_t val); + if (val.val != 42) begin + $display("Mismatch expected:%s actual:%s", "42", val.val); + $stop; + end + endfunction + function void e_unpack_struct_1d(input unpack_struct_t val[2]); + if (val[0].val != 43) begin + $display("Mismatch expected:%s actual:%s", "43", val[0].val); + $stop; + end + if (val[1].val != 44) begin + $display("Mismatch expected:%s actual:%s", "44", val[1].val); + $stop; + end + endfunction + function void e_unpack_struct_2d(input unpack_struct_t val[3][2]); + if (val[0][1].val != 45) begin + $display("Mismatch expected:%s actual:%s", "45", val[0][1].val); + $stop; + end + if (val[1][1].val != 46) begin + $display("Mismatch expected:%s actual:%s", "46", val[1][1].val); + $stop; + end + if (val[2][1].val != 47) begin + $display("Mismatch expected:%s actual:%s", "47", val[2][1].val); + $stop; + end + endfunction + function void e_unpack_struct_3d(input unpack_struct_array_t val); + if (val[0][0][0].val != 48) begin + $display("Mismatch expected:%s actual:%s", "48", val[0][0][0].val); + $stop; + end + if (val[1][0][0].val != 49) begin + $display("Mismatch expected:%s actual:%s", "49", val[1][0][0].val); + $stop; + end + if (val[2][0][0].val != 50) begin + $display("Mismatch expected:%s actual:%s", "50", val[2][0][0].val); + $stop; + end + if (val[3][0][0].val != 51) begin + $display("Mismatch expected:%s actual:%s", "51", val[3][0][0].val); + $stop; + end + endfunction +`endif + + //====================================================================== + // Invoke all imported functions + //====================================================================== + + import "DPI-C" context function void check_exports(); + + initial begin + byte_array_t byte_array; + byte_unsigned_array_t byte_unsigned_array; + shortint_array_t shortint_array; + shortint_unsigned_array_t shortint_unsigned_array; + int_array_t int_array; + int_unsigned_array_t int_unsigned_array; + longint_array_t longint_array; + longint_unsigned_array_t longint_unsigned_array; +`ifndef NO_TIME + time_array_t time_array; +`endif +`ifndef NO_INTEGER + integer_array_t integer_array; +`endif + real_array_t real_array; +`ifndef NO_SHORTREAL + shortreal_array_t shortreal_array; +`endif + chandle_array_t chandle_array; + string_array_t string_array; + bit7_array_t bit7_array; + bit121_array_t bit121_array; + logic7_array_t logic7_array; + logic121_array_t logic121_array; + pack_struct_array_t pack_struct_array; +`ifndef NO_UNPACK_STRUCT + unpack_struct_array_t unpack_struct_array; +`endif + + `SET_VALUES(byte_array); + i_byte_0d(byte_array[3][2][1]); + i_byte_1d(byte_array[2][1]); + i_byte_2d(byte_array[1]); + i_byte_3d(byte_array); + + `SET_VALUES(byte_unsigned_array); + i_byte_unsigned_0d(byte_unsigned_array[3][2][1]); + i_byte_unsigned_1d(byte_unsigned_array[2][1]); + i_byte_unsigned_2d(byte_unsigned_array[1]); + i_byte_unsigned_3d(byte_unsigned_array); + + `SET_VALUES(shortint_array); + i_shortint_0d(shortint_array[3][2][1]); + i_shortint_1d(shortint_array[2][1]); + i_shortint_2d(shortint_array[1]); + i_shortint_3d(shortint_array); + + `SET_VALUES(shortint_unsigned_array); + i_shortint_unsigned_0d(shortint_unsigned_array[3][2][1]); + i_shortint_unsigned_1d(shortint_unsigned_array[2][1]); + i_shortint_unsigned_2d(shortint_unsigned_array[1]); + i_shortint_unsigned_3d(shortint_unsigned_array); + + `SET_VALUES(int_array); + i_int_0d(int_array[3][2][1]); + i_int_1d(int_array[2][1]); + i_int_2d(int_array[1]); + i_int_3d(int_array); + + `SET_VALUES(int_unsigned_array); + i_int_unsigned_0d(int_unsigned_array[3][2][1]); + i_int_unsigned_1d(int_unsigned_array[2][1]); + i_int_unsigned_2d(int_unsigned_array[1]); + i_int_unsigned_3d(int_unsigned_array); + + `SET_VALUES(longint_array); + i_longint_0d(longint_array[3][2][1]); + i_longint_1d(longint_array[2][1]); + i_longint_2d(longint_array[1]); + i_longint_3d(longint_array); + + `SET_VALUES(longint_unsigned_array); + i_longint_unsigned_0d(longint_unsigned_array[3][2][1]); + i_longint_unsigned_1d(longint_unsigned_array[2][1]); + i_longint_unsigned_2d(longint_unsigned_array[1]); + i_longint_unsigned_3d(longint_unsigned_array); + +`ifndef NO_TIME + `SET_VALUES(time_array); + i_time_0d(time_array[3][2][1]); + i_time_1d(time_array[2][1]); + i_time_2d(time_array[1]); + i_time_3d(time_array); +`endif + +`ifndef NO_INTEGER + `SET_VALUES(integer_array); + i_integer_0d(integer_array[3][2][1]); + i_integer_1d(integer_array[2][1]); + i_integer_2d(integer_array[1]); + i_integer_3d(integer_array); +`endif + + `SET_VALUES(real_array); + i_real_0d(real_array[3][2][1]); + i_real_1d(real_array[2][1]); + i_real_2d(real_array[1]); + i_real_3d(real_array); + +`ifndef NO_SHORTREAL + `SET_VALUES(shortreal_array); + i_shortreal_0d(shortreal_array[3][2][1]); + i_shortreal_1d(shortreal_array[2][1]); + i_shortreal_2d(shortreal_array[1]); + i_shortreal_3d(shortreal_array); +`endif + + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) + chandle_array[i][j][k] = null; + + chandle_array[3][2][1] = get_non_null(); + i_chandle_0d(chandle_array[3][2][1]); + chandle_array[2][1][0] = get_non_null(); + chandle_array[2][1][1] = get_non_null(); + i_chandle_1d(chandle_array[2][1]); + chandle_array[1][0][1] = get_non_null(); + chandle_array[1][1][1] = get_non_null(); + chandle_array[1][2][1] = get_non_null(); + i_chandle_2d(chandle_array[1]); + chandle_array[0][0][0] = get_non_null(); + chandle_array[1][0][0] = get_non_null(); + chandle_array[2][0][0] = get_non_null(); + chandle_array[3][0][0] = get_non_null(); + i_chandle_3d(chandle_array); + + string_array[3][2][1] = "42"; + string_array[2][1][0] = "43"; string_array[2][1][1] = "44"; + string_array[1][0][1] = "45"; string_array[1][1][1] = "46"; string_array[1][2][1] = "47"; + string_array[0][0][0] = "48"; string_array[1][0][0] = "49"; string_array[2][0][0] = "50"; string_array[3][0][0] = "51"; + i_string_0d(string_array[3][2][1]); + i_string_1d(string_array[2][1]); + i_string_2d(string_array[1]); + i_string_3d(string_array); + + `SET_VALUES(bit7_array); + i_bit7_0d(bit7_array[3][2][1]); + i_bit7_1d(bit7_array[2][1]); + i_bit7_2d(bit7_array[1]); + i_bit7_3d(bit7_array); + + `SET_VALUES(bit121_array); + i_bit121_0d(bit121_array[3][2][1]); + i_bit121_1d(bit121_array[2][1]); + i_bit121_2d(bit121_array[1]); + i_bit121_3d(bit121_array); + + `SET_VALUES(logic7_array); + i_logic7_0d(logic7_array[3][2][1]); + i_logic7_1d(logic7_array[2][1]); + i_logic7_2d(logic7_array[1]); + i_logic7_3d(logic7_array); + + `SET_VALUES(logic121_array); + i_logic121_0d(logic121_array[3][2][1]); + i_logic121_1d(logic121_array[2][1]); + i_logic121_2d(logic121_array[1]); + i_logic121_3d(logic121_array); + + `SET_VALUES(pack_struct_array); + i_pack_struct_0d(pack_struct_array[3][2][1]); + i_pack_struct_1d(pack_struct_array[2][1]); + i_pack_struct_2d(pack_struct_array[1]); + i_pack_struct_3d(pack_struct_array); + +`ifndef NO_UNPACK_STRUCT + unpack_struct_array[3][2][1].val = 42; + unpack_struct_array[2][1][0].val = 43; + unpack_struct_array[2][1][1].val = 44; + + unpack_struct_array[1][0][1].val = 45; + unpack_struct_array[1][1][1].val = 46; + unpack_struct_array[1][2][1].val = 47; + + unpack_struct_array[0][0][0].val = 48; + unpack_struct_array[1][0][0].val = 49; + unpack_struct_array[2][0][0].val = 50; + unpack_struct_array[3][0][0].val = 51; + i_unpack_struct_0d(unpack_struct_array[3][2][1]); + i_unpack_struct_1d(unpack_struct_array[2][1]); + i_unpack_struct_2d(unpack_struct_array[1]); + i_unpack_struct_3d(unpack_struct_array); +`endif + + check_exports(); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_arg_input_unpack__Dpi.out b/test_regress/t/t_dpi_arg_input_unpack__Dpi.out new file mode 100644 index 000000000..dd53f2061 --- /dev/null +++ b/test_regress/t/t_dpi_arg_input_unpack__Dpi.out @@ -0,0 +1,313 @@ +// Verilated -*- C++ -*- +// DESCRIPTION: Verilator output: Prototypes for DPI import and export functions. +// +// Verilator includes this file in all generated .cpp files that use DPI functions. +// Manually include this file where DPI .c import functions are declared to ensure +// the C functions match the expectations of the DPI imports. + +#include "svdpi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + // DPI EXPORTS + // DPI export at t/t_dpi_arg_input_unpack.v:501:18 + extern void e_bit121_0d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:502:18 + extern void e_bit121_1d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:503:18 + extern void e_bit121_2d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:504:18 + extern void e_bit121_3d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:496:18 + extern void e_bit7_0d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:497:18 + extern void e_bit7_1d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:498:18 + extern void e_bit7_2d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:499:18 + extern void e_bit7_3d(const svBitVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:332:18 + extern void e_byte_0d(char val); + // DPI export at t/t_dpi_arg_input_unpack.v:333:18 + extern void e_byte_1d(const char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:334:18 + extern void e_byte_2d(const char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:335:18 + extern void e_byte_3d(const char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:337:18 + extern void e_byte_unsigned_0d(unsigned char val); + // DPI export at t/t_dpi_arg_input_unpack.v:338:18 + extern void e_byte_unsigned_1d(const unsigned char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:339:18 + extern void e_byte_unsigned_2d(const unsigned char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:340:18 + extern void e_byte_unsigned_3d(const unsigned char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:398:18 + extern void e_chandle_0d(void* val); + // DPI export at t/t_dpi_arg_input_unpack.v:404:18 + extern void e_chandle_1d(const void** val); + // DPI export at t/t_dpi_arg_input_unpack.v:414:18 + extern void e_chandle_2d(const void** val); + // DPI export at t/t_dpi_arg_input_unpack.v:428:18 + extern void e_chandle_3d(const void** val); + // DPI export at t/t_dpi_arg_input_unpack.v:352:18 + extern void e_int_0d(int val); + // DPI export at t/t_dpi_arg_input_unpack.v:353:18 + extern void e_int_1d(const int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:354:18 + extern void e_int_2d(const int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:355:18 + extern void e_int_3d(const int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:357:18 + extern void e_int_unsigned_0d(unsigned int val); + // DPI export at t/t_dpi_arg_input_unpack.v:358:18 + extern void e_int_unsigned_1d(const unsigned int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:359:18 + extern void e_int_unsigned_2d(const unsigned int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:360:18 + extern void e_int_unsigned_3d(const unsigned int* val); + // DPI export at t/t_dpi_arg_input_unpack.v:380:18 + extern void e_integer_0d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:381:18 + extern void e_integer_1d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:382:18 + extern void e_integer_2d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:383:18 + extern void e_integer_3d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:511:18 + extern void e_logic121_0d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:512:18 + extern void e_logic121_1d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:513:18 + extern void e_logic121_2d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:514:18 + extern void e_logic121_3d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:506:18 + extern void e_logic7_0d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:507:18 + extern void e_logic7_1d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:508:18 + extern void e_logic7_2d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:509:18 + extern void e_logic7_3d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:362:18 + extern void e_longint_0d(long long val); + // DPI export at t/t_dpi_arg_input_unpack.v:363:18 + extern void e_longint_1d(const long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:364:18 + extern void e_longint_2d(const long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:365:18 + extern void e_longint_3d(const long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:367:18 + extern void e_longint_unsigned_0d(unsigned long long val); + // DPI export at t/t_dpi_arg_input_unpack.v:368:18 + extern void e_longint_unsigned_1d(const unsigned long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:369:18 + extern void e_longint_unsigned_2d(const unsigned long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:370:18 + extern void e_longint_unsigned_3d(const unsigned long long* val); + // DPI export at t/t_dpi_arg_input_unpack.v:516:18 + extern void e_pack_struct_0d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:517:18 + extern void e_pack_struct_1d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:518:18 + extern void e_pack_struct_2d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:519:18 + extern void e_pack_struct_3d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:386:18 + extern void e_real_0d(double val); + // DPI export at t/t_dpi_arg_input_unpack.v:387:18 + extern void e_real_1d(const double* val); + // DPI export at t/t_dpi_arg_input_unpack.v:388:18 + extern void e_real_2d(const double* val); + // DPI export at t/t_dpi_arg_input_unpack.v:389:18 + extern void e_real_3d(const double* val); + // DPI export at t/t_dpi_arg_input_unpack.v:342:18 + extern void e_shortint_0d(short val); + // DPI export at t/t_dpi_arg_input_unpack.v:343:18 + extern void e_shortint_1d(const short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:344:18 + extern void e_shortint_2d(const short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:345:18 + extern void e_shortint_3d(const short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:347:18 + extern void e_shortint_unsigned_0d(unsigned short val); + // DPI export at t/t_dpi_arg_input_unpack.v:348:18 + extern void e_shortint_unsigned_1d(const unsigned short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:349:18 + extern void e_shortint_unsigned_2d(const unsigned short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:350:18 + extern void e_shortint_unsigned_3d(const unsigned short* val); + // DPI export at t/t_dpi_arg_input_unpack.v:447:18 + extern void e_string_0d(const char* val); + // DPI export at t/t_dpi_arg_input_unpack.v:453:18 + extern void e_string_1d(const char** val); + // DPI export at t/t_dpi_arg_input_unpack.v:463:18 + extern void e_string_2d(const char** val); + // DPI export at t/t_dpi_arg_input_unpack.v:477:18 + extern void e_string_3d(const char** val); + // DPI export at t/t_dpi_arg_input_unpack.v:373:18 + extern void e_time_0d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:374:18 + extern void e_time_1d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:375:18 + extern void e_time_2d(const svLogicVecVal* val); + // DPI export at t/t_dpi_arg_input_unpack.v:376:18 + extern void e_time_3d(const svLogicVecVal* val); + + // DPI IMPORTS + // DPI import at t/t_dpi_arg_input_unpack.v:576:41 + extern void check_exports(); + // DPI import at t/t_dpi_arg_input_unpack.v:106:36 + extern void* get_non_null(); + // DPI import at t/t_dpi_arg_input_unpack.v:189:33 + extern void i_bit121_0d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:190:33 + extern void i_bit121_1d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:191:33 + extern void i_bit121_2d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:192:33 + extern void i_bit121_3d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:184:33 + extern void i_bit7_0d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:185:33 + extern void i_bit7_1d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:186:33 + extern void i_bit7_2d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:187:33 + extern void i_bit7_3d(const svBitVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:108:33 + extern void i_byte_0d(char val); + // DPI import at t/t_dpi_arg_input_unpack.v:109:33 + extern void i_byte_1d(const char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:110:33 + extern void i_byte_2d(const char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:111:33 + extern void i_byte_3d(const char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:113:33 + extern void i_byte_unsigned_0d(unsigned char val); + // DPI import at t/t_dpi_arg_input_unpack.v:114:33 + extern void i_byte_unsigned_1d(const unsigned char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:115:33 + extern void i_byte_unsigned_2d(const unsigned char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:116:33 + extern void i_byte_unsigned_3d(const unsigned char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:174:33 + extern void i_chandle_0d(void* val); + // DPI import at t/t_dpi_arg_input_unpack.v:175:33 + extern void i_chandle_1d(const void** val); + // DPI import at t/t_dpi_arg_input_unpack.v:176:33 + extern void i_chandle_2d(const void** val); + // DPI import at t/t_dpi_arg_input_unpack.v:177:33 + extern void i_chandle_3d(const void** val); + // DPI import at t/t_dpi_arg_input_unpack.v:128:33 + extern void i_int_0d(int val); + // DPI import at t/t_dpi_arg_input_unpack.v:129:33 + extern void i_int_1d(const int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:130:33 + extern void i_int_2d(const int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:131:33 + extern void i_int_3d(const int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:133:33 + extern void i_int_unsigned_0d(unsigned int val); + // DPI import at t/t_dpi_arg_input_unpack.v:134:33 + extern void i_int_unsigned_1d(const unsigned int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:135:33 + extern void i_int_unsigned_2d(const unsigned int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:136:33 + extern void i_int_unsigned_3d(const unsigned int* val); + // DPI import at t/t_dpi_arg_input_unpack.v:156:33 + extern void i_integer_0d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:157:33 + extern void i_integer_1d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:158:33 + extern void i_integer_2d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:159:33 + extern void i_integer_3d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:199:33 + extern void i_logic121_0d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:200:33 + extern void i_logic121_1d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:201:33 + extern void i_logic121_2d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:202:33 + extern void i_logic121_3d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:194:33 + extern void i_logic7_0d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:195:33 + extern void i_logic7_1d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:196:33 + extern void i_logic7_2d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:197:33 + extern void i_logic7_3d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:138:33 + extern void i_longint_0d(long long val); + // DPI import at t/t_dpi_arg_input_unpack.v:139:33 + extern void i_longint_1d(const long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:140:33 + extern void i_longint_2d(const long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:141:33 + extern void i_longint_3d(const long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:143:33 + extern void i_longint_unsigned_0d(unsigned long long val); + // DPI import at t/t_dpi_arg_input_unpack.v:144:33 + extern void i_longint_unsigned_1d(const unsigned long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:145:33 + extern void i_longint_unsigned_2d(const unsigned long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:146:33 + extern void i_longint_unsigned_3d(const unsigned long long* val); + // DPI import at t/t_dpi_arg_input_unpack.v:204:33 + extern void i_pack_struct_0d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:205:33 + extern void i_pack_struct_1d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:206:33 + extern void i_pack_struct_2d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:207:33 + extern void i_pack_struct_3d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:162:33 + extern void i_real_0d(double val); + // DPI import at t/t_dpi_arg_input_unpack.v:163:33 + extern void i_real_1d(const double* val); + // DPI import at t/t_dpi_arg_input_unpack.v:164:33 + extern void i_real_2d(const double* val); + // DPI import at t/t_dpi_arg_input_unpack.v:165:33 + extern void i_real_3d(const double* val); + // DPI import at t/t_dpi_arg_input_unpack.v:118:33 + extern void i_shortint_0d(short val); + // DPI import at t/t_dpi_arg_input_unpack.v:119:33 + extern void i_shortint_1d(const short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:120:33 + extern void i_shortint_2d(const short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:121:33 + extern void i_shortint_3d(const short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:123:33 + extern void i_shortint_unsigned_0d(unsigned short val); + // DPI import at t/t_dpi_arg_input_unpack.v:124:33 + extern void i_shortint_unsigned_1d(const unsigned short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:125:33 + extern void i_shortint_unsigned_2d(const unsigned short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:126:33 + extern void i_shortint_unsigned_3d(const unsigned short* val); + // DPI import at t/t_dpi_arg_input_unpack.v:179:33 + extern void i_string_0d(const char* val); + // DPI import at t/t_dpi_arg_input_unpack.v:180:33 + extern void i_string_1d(const char** val); + // DPI import at t/t_dpi_arg_input_unpack.v:181:33 + extern void i_string_2d(const char** val); + // DPI import at t/t_dpi_arg_input_unpack.v:182:33 + extern void i_string_3d(const char** val); + // DPI import at t/t_dpi_arg_input_unpack.v:149:33 + extern void i_time_0d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:150:33 + extern void i_time_1d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:151:33 + extern void i_time_2d(const svLogicVecVal* val); + // DPI import at t/t_dpi_arg_input_unpack.v:152:33 + extern void i_time_3d(const svLogicVecVal* val); + +#ifdef __cplusplus +} +#endif diff --git a/test_regress/t/t_dpi_arg_output_unpack.cpp b/test_regress/t/t_dpi_arg_output_unpack.cpp new file mode 100644 index 000000000..417e29cb1 --- /dev/null +++ b/test_regress/t/t_dpi_arg_output_unpack.cpp @@ -0,0 +1,655 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 +// +//************************************************************************* + +#include +#include +#include +#include +#include + +// clang-format off +#if defined(NCSC) +// Used by NC's svdpi.h to pick up svLogicVecVal with _.aval and _.bval fields, +// rather than the IEEE 1800-2005 version which has _.a and _.b fields. +# define DPI_COMPATIBILITY_VERSION_1800v2012 +#endif + +#include "svdpi.h" + +#if defined(VERILATOR) // Verilator +# include "Vt_dpi_arg_output_unpack__Dpi.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_SHORTREAL +# define NO_UNPACK_STRUCT +# define CONSTARG const +#elif defined(VCS) // VCS +# include "../vc_hdrs.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_TIME +# define CONSTARG const +#elif defined(NCSC) // NC +# include "dpi-exp.h" +# include "dpi-imp.h" +typedef long long sv_longint_t; +typedef unsigned long long sv_longint_unsigned_t; +# define NO_TIME +# define NO_INTEGER +# define NO_SHORTREAL +// Sadly NC does not declare pass-by reference input arguments as const +# define CONSTARG +#elif defined(MS) // ModelSim +# include "dpi.h" +typedef int64_t sv_longint_t; +typedef uint64_t sv_longint_unsigned_t; +# define CONSTARG const +#else +# error "Unknown simulator for DPI test" +#endif +// clang-format on + +//====================================================================== +// Implementations of imported functions +//====================================================================== + +namespace { // unnamed namespace + +const bool VERBOSE_MESSAGE = false; + +#define stop() \ + do { \ + printf(__FILE__ ":%d Bad value\n", __LINE__); \ + abort(); \ + } while (0) + +void set_uint(svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselLogic(v0, i, (val >> i) & 1); + else + svPutBitselLogic(v0, i, 0); + } +} + +void set_uint(svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + if (i < 64) + svPutBitselBit(v0, i, (val >> i) & 1); + else + svPutBitselBit(v0, i, 0); + } +} + +template void set_0d(T* v) { *v = 42; } +template void set_1d(T* v) { + v[0] = 43; + v[1] = 44; +} + +template void set_2d(T* v) { + v[0 * 2 + 1] = 45; + v[1 * 2 + 1] = 46; + v[2 * 2 + 1] = 47; +} +template void set_3d(T* v) { + v[(0 * 3 + 0) * 2 + 0] = 48; + v[(1 * 3 + 0) * 2 + 0] = 49; + v[(2 * 3 + 0) * 2 + 0] = 50; + v[(3 * 3 + 0) * 2 + 0] = 51; +} + +void set_0d(svLogicVecVal* v, int bitwidth) { set_uint(v, 42, bitwidth); } + +void set_1d(svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + 0 * unit, 43, bitwidth); + set_uint(v + 1 * unit, 44, bitwidth); +} + +void set_2d(svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + (0 * 2 + 1) * unit, 45, bitwidth); + set_uint(v + (1 * 2 + 1) * unit, 46, bitwidth); + set_uint(v + (2 * 2 + 1) * unit, 47, bitwidth); +} + +void set_3d(svLogicVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + ((0 * 3 + 0) * 2 + 0) * unit, 48, bitwidth); + set_uint(v + ((1 * 3 + 0) * 2 + 0) * unit, 49, bitwidth); + set_uint(v + ((2 * 3 + 0) * 2 + 0) * unit, 50, bitwidth); + set_uint(v + ((3 * 3 + 0) * 2 + 0) * unit, 51, bitwidth); +} + +void set_0d(svBitVecVal* v, int bitwidth) { set_uint(v, 42, bitwidth); } + +void set_1d(svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + 0 * unit, 43, bitwidth); + set_uint(v + 1 * unit, 44, bitwidth); +} + +void set_2d(svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + (0 * 2 + 1) * unit, 45, bitwidth); + set_uint(v + (1 * 2 + 1) * unit, 46, bitwidth); + set_uint(v + (2 * 2 + 1) * unit, 47, bitwidth); +} + +void set_3d(svBitVecVal* v, int bitwidth) { + const int unit = (bitwidth + 31) / 32; + set_uint(v + ((0 * 3 + 0) * 2 + 0) * unit, 48, bitwidth); + set_uint(v + ((1 * 3 + 0) * 2 + 0) * unit, 49, bitwidth); + set_uint(v + ((2 * 3 + 0) * 2 + 0) * unit, 50, bitwidth); + set_uint(v + ((3 * 3 + 0) * 2 + 0) * unit, 51, bitwidth); +} + +template bool compare(const T& act, const T& exp) { + if (exp == act) { + if (VERBOSE_MESSAGE) { std::cout << "OK Exp:" << exp << " actual:" << act << std::endl; } + return true; + } else { + std::cout << "NG Exp:" << exp << " actual:" << act << std::endl; + return false; + } +} + +template bool check_0d(T v) { return compare(v, 42); } +template bool check_1d(const T (&v)[2]) { + return compare(v[0], 43) && compare(v[1], 44); +} +template bool check_2d(const T (&v)[3][2]) { + return compare(v[0][1], 45) && compare(v[1][1], 46) && compare(v[2][1], 47); +} +template bool check_3d(const T (&v)[4][3][2]) { + return compare(v[0][0][0], 48) && compare(v[1][0][0], 49) && compare(v[2][0][0], 50) + && compare(v[3][0][0], 51); +} + +bool compare(const svLogicVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselLogic(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +bool compare(const svBitVecVal* v0, sv_longint_unsigned_t val, int bitwidth) { + for (int i = 0; i < bitwidth; ++i) { + const bool act_bit = svGetBitselBit(v0, i); + const bool exp_bit = (i < 64) ? ((val >> i) & 1) : false; + if (act_bit != exp_bit) { + std::cout << "Mismatch at bit:" << i << " exp:" << exp_bit << " act:" << act_bit; + return false; + } + } + if (VERBOSE_MESSAGE) { + std::cout << "OK " << val << " as expected (width:" << bitwidth << ")" << std::endl; + } + return true; +} + +template bool check_0d(const T (&v)[N], int bitwidth) { + return compare(v, 42, bitwidth); +} +template bool check_1d(const T (&v)[2][N], int bitwidth) { + return compare(v[0], 43, bitwidth) && compare(v[1], 44, bitwidth); +} +template bool check_2d(const T (&v)[3][2][N], int bitwidth) { + return compare(v[0][1], 45, bitwidth) && compare(v[1][1], 46, bitwidth) + && compare(v[2][1], 47, bitwidth); +} +template bool check_3d(const T (&v)[4][3][2][N], int bitwidth) { + return compare(v[0][0][0], 48, bitwidth) && compare(v[1][0][0], 49, bitwidth) + && compare(v[2][0][0], 50, bitwidth) && compare(v[3][0][0], 51, bitwidth); +} + +} // unnamed namespace + +void* get_non_null() { + static int v; + return &v; +} + +void i_byte_0d(char* v) { set_0d(v); } +void i_byte_1d(char* v) { set_1d(v); } +void i_byte_2d(char* v) { set_2d(v); } +void i_byte_3d(char* v) { set_3d(v); } + +void i_byte_unsigned_0d(unsigned char* v) { set_0d(v); } +void i_byte_unsigned_1d(unsigned char* v) { set_1d(v); } +void i_byte_unsigned_2d(unsigned char* v) { set_2d(v); } +void i_byte_unsigned_3d(unsigned char* v) { set_3d(v); } + +void i_shortint_0d(short* v) { set_0d(v); } +void i_shortint_1d(short* v) { set_1d(v); } +void i_shortint_2d(short* v) { set_2d(v); } +void i_shortint_3d(short* v) { set_3d(v); } + +void i_shortint_unsigned_0d(unsigned short* v) { set_0d(v); } +void i_shortint_unsigned_1d(unsigned short* v) { set_1d(v); } +void i_shortint_unsigned_2d(unsigned short* v) { set_2d(v); } +void i_shortint_unsigned_3d(unsigned short* v) { set_3d(v); } + +void i_int_0d(int* v) { set_0d(v); } +void i_int_1d(int* v) { set_1d(v); } +void i_int_2d(int* v) { set_2d(v); } +void i_int_3d(int* v) { set_3d(v); } + +void i_int_unsigned_0d(unsigned int* v) { set_0d(v); } +void i_int_unsigned_1d(unsigned int* v) { set_1d(v); } +void i_int_unsigned_2d(unsigned int* v) { set_2d(v); } +void i_int_unsigned_3d(unsigned int* v) { set_3d(v); } + +void i_longint_0d(sv_longint_t* v) { set_0d(v); } +void i_longint_1d(sv_longint_t* v) { set_1d(v); } +void i_longint_2d(sv_longint_t* v) { set_2d(v); } +void i_longint_3d(sv_longint_t* v) { set_3d(v); } + +void i_longint_unsigned_0d(sv_longint_unsigned_t* v) { set_0d(v); } +void i_longint_unsigned_1d(sv_longint_unsigned_t* v) { set_1d(v); } +void i_longint_unsigned_2d(sv_longint_unsigned_t* v) { set_2d(v); } +void i_longint_unsigned_3d(sv_longint_unsigned_t* v) { set_3d(v); } + +#ifndef NO_TIME +void i_time_0d(svLogicVecVal* v) { set_0d(v, 64); } +void i_time_1d(svLogicVecVal* v) { set_1d(v, 64); } +void i_time_2d(svLogicVecVal* v) { set_2d(v, 64); } +void i_time_3d(svLogicVecVal* v) { set_3d(v, 64); } +#endif + +#ifndef NO_INTEGER +void i_integer_0d(svLogicVecVal* v) { set_0d(v, 32); } +void i_integer_1d(svLogicVecVal* v) { set_1d(v, 32); } +void i_integer_2d(svLogicVecVal* v) { set_2d(v, 32); } +void i_integer_3d(svLogicVecVal* v) { set_3d(v, 32); } +#endif + +void i_real_0d(double* v) { set_0d(v); } +void i_real_1d(double* v) { set_1d(v); } +void i_real_2d(double* v) { set_2d(v); } +void i_real_3d(double* v) { set_3d(v); } + +#ifndef NO_SHORTREAL +void i_shortreal_0d(float* v) { set_0d(v); } +void i_shortreal_1d(float* v) { set_1d(v); } +void i_shortreal_2d(float* v) { set_2d(v); } +void i_shortreal_3d(float* v) { set_3d(v); } +#endif + +void i_chandle_0d(void** v) { v[0] = get_non_null(); } +void i_chandle_1d(void** v) { + v[0] = get_non_null(); + v[1] = get_non_null(); +} +void i_chandle_2d(void** v) { + v[2 * 0 + 1] = get_non_null(); + v[2 * 1 + 1] = get_non_null(); + v[2 * 2 + 1] = get_non_null(); +} +void i_chandle_3d(void** v) { + v[(0 * 3 + 0) * 2 + 0] = get_non_null(); + v[(1 * 3 + 0) * 2 + 0] = get_non_null(); + v[(2 * 3 + 0) * 2 + 0] = get_non_null(); + v[(3 * 3 + 0) * 2 + 0] = get_non_null(); +} + +void i_string_0d(const char** v) { + static const char s[] = "42"; + v[0] = s; +} +void i_string_1d(const char** v) { + static const char s0[] = "43"; + static const char s1[] = "44"; + v[0] = s0; + v[1] = s1; +} +void i_string_2d(const char** v) { + static const char empty[] = ""; + static const char s0[] = "45"; + static const char s1[] = "46"; + static const char s2[] = "47"; + for (int i = 0; i < 3 * 2; ++i) v[i] = empty; + v[2 * 0 + 1] = s0; + v[2 * 1 + 1] = s1; + v[2 * 2 + 1] = s2; +} +void i_string_3d(const char** v) { + static const char empty[] = ""; + static const char s0[] = "48"; + static const char s1[] = "49"; + static const char s2[] = "50"; + static const char s3[] = "51"; + for (int i = 0; i < 4 * 3 * 2; ++i) v[i] = empty; + v[(0 * 3 + 0) * 2 + 0] = s0; + v[(1 * 3 + 0) * 2 + 0] = s1; + v[(2 * 3 + 0) * 2 + 0] = s2; + v[(3 * 3 + 0) * 2 + 0] = s3; +} + +void i_bit7_0d(svBitVecVal* v) { set_0d(v, 7); } +void i_bit7_1d(svBitVecVal* v) { set_1d(v, 7); } +void i_bit7_2d(svBitVecVal* v) { set_2d(v, 7); } +void i_bit7_3d(svBitVecVal* v) { set_3d(v, 7); } + +void i_bit121_0d(svBitVecVal* v) { set_0d(v, 121); } +void i_bit121_1d(svBitVecVal* v) { set_1d(v, 121); } +void i_bit121_2d(svBitVecVal* v) { set_2d(v, 121); } +void i_bit121_3d(svBitVecVal* v) { set_3d(v, 121); } + +void i_logic7_0d(svLogicVecVal* v) { set_0d(v, 7); } +void i_logic7_1d(svLogicVecVal* v) { set_1d(v, 7); } +void i_logic7_2d(svLogicVecVal* v) { set_2d(v, 7); } +void i_logic7_3d(svLogicVecVal* v) { set_3d(v, 7); } + +void i_logic121_0d(svLogicVecVal* v) { set_0d(v, 121); } +void i_logic121_1d(svLogicVecVal* v) { set_1d(v, 121); } +void i_logic121_2d(svLogicVecVal* v) { set_2d(v, 121); } +void i_logic121_3d(svLogicVecVal* v) { set_3d(v, 121); } + +void i_pack_struct_0d(svLogicVecVal* v) { set_0d(v, 7); } +void i_pack_struct_1d(svLogicVecVal* v) { set_1d(v, 7); } +void i_pack_struct_2d(svLogicVecVal* v) { set_2d(v, 7); } +void i_pack_struct_3d(svLogicVecVal* v) { set_3d(v, 7); } + +#ifndef NO_UNPACK_STRUCT +void i_unpack_struct_0d(unpack_struct_t* v) { set_uint(v->val, 42, 121); } +void i_unpack_struct_1d(unpack_struct_t* v) { + set_uint(v[0].val, 43, 121); + set_uint(v[1].val, 44, 121); +} +void i_unpack_struct_2d(unpack_struct_t* v) { + set_uint(v[0 * 2 + 1].val, 45, 121); + set_uint(v[1 * 2 + 1].val, 46, 121); + set_uint(v[2 * 2 + 1].val, 47, 121); +} +void i_unpack_struct_3d(unpack_struct_t* v) { + set_uint(v[(0 * 3 + 0) * 2 + 0].val, 48, 121); + set_uint(v[(1 * 3 + 0) * 2 + 0].val, 49, 121); + set_uint(v[(2 * 3 + 0) * 2 + 0].val, 50, 121); + set_uint(v[(3 * 3 + 0) * 2 + 0].val, 51, 121); +} +#endif + +void check_exports() { + { + char byte_array[4][3][2]; + e_byte_0d(&byte_array[3][2][1]); + if (!check_0d(byte_array[3][2][1])) stop(); + e_byte_1d(&byte_array[2][1][0]); + if (!check_1d(byte_array[2][1])) stop(); + e_byte_2d(&byte_array[1][0][0]); + if (!check_2d(byte_array[1])) stop(); + e_byte_3d(&byte_array[0][0][0]); + if (!check_3d(byte_array)) stop(); + } + { + unsigned char byte_unsigned_array[4][3][2]; + e_byte_unsigned_0d(&byte_unsigned_array[3][2][1]); + if (!check_0d(byte_unsigned_array[3][2][1])) stop(); + e_byte_unsigned_1d(&byte_unsigned_array[2][1][0]); + if (!check_1d(byte_unsigned_array[2][1])) stop(); + e_byte_unsigned_2d(&byte_unsigned_array[1][0][0]); + if (!check_2d(byte_unsigned_array[1])) stop(); + e_byte_unsigned_3d(&byte_unsigned_array[0][0][0]); + if (!check_3d(byte_unsigned_array)) stop(); + } + { + short shortint_array[4][3][2]; + e_shortint_0d(&shortint_array[3][2][1]); + if (!check_0d(shortint_array[3][2][1])) stop(); + e_shortint_1d(&shortint_array[2][1][0]); + if (!check_1d(shortint_array[2][1])) stop(); + e_shortint_2d(&shortint_array[1][0][0]); + if (!check_2d(shortint_array[1])) stop(); + e_shortint_3d(&shortint_array[0][0][0]); + if (!check_3d(shortint_array)) stop(); + } + { + unsigned short shortint_unsigned_array[4][3][2]; + e_shortint_unsigned_0d(&shortint_unsigned_array[3][2][1]); + if (!check_0d(shortint_unsigned_array[3][2][1])) stop(); + e_shortint_unsigned_1d(&shortint_unsigned_array[2][1][0]); + if (!check_1d(shortint_unsigned_array[2][1])) stop(); + e_shortint_unsigned_2d(&shortint_unsigned_array[1][0][0]); + if (!check_2d(shortint_unsigned_array[1])) stop(); + e_shortint_unsigned_3d(&shortint_unsigned_array[0][0][0]); + if (!check_3d(shortint_unsigned_array)) stop(); + } + + { + int int_array[4][3][2]; + e_int_0d(&int_array[3][2][1]); + if (!check_0d(int_array[3][2][1])) stop(); + e_int_1d(&int_array[2][1][0]); + if (!check_1d(int_array[2][1])) stop(); + e_int_2d(&int_array[1][0][0]); + if (!check_2d(int_array[1])) stop(); + e_int_3d(&int_array[0][0][0]); + if (!check_3d(int_array)) stop(); + } + { + unsigned int int_unsigned_array[4][3][2]; + e_int_unsigned_0d(&int_unsigned_array[3][2][1]); + if (!check_0d(int_unsigned_array[3][2][1])) stop(); + e_int_unsigned_1d(&int_unsigned_array[2][1][0]); + if (!check_1d(int_unsigned_array[2][1])) stop(); + e_int_unsigned_2d(&int_unsigned_array[1][0][0]); + if (!check_2d(int_unsigned_array[1])) stop(); + e_int_unsigned_3d(&int_unsigned_array[0][0][0]); + if (!check_3d(int_unsigned_array)) stop(); + } + + { + sv_longint_t longint_array[4][3][2]; + e_longint_0d(&longint_array[3][2][1]); + if (!check_0d(longint_array[3][2][1])) stop(); + e_longint_1d(&longint_array[2][1][0]); + if (!check_1d(longint_array[2][1])) stop(); + e_longint_2d(&longint_array[1][0][0]); + if (!check_2d(longint_array[1])) stop(); + e_longint_3d(&longint_array[0][0][0]); + if (!check_3d(longint_array)) stop(); + } + { + sv_longint_unsigned_t longint_unsigned_array[4][3][2]; + e_longint_unsigned_0d(&longint_unsigned_array[3][2][1]); + if (!check_0d(longint_unsigned_array[3][2][1])) stop(); + e_longint_unsigned_1d(&longint_unsigned_array[2][1][0]); + if (!check_1d(longint_unsigned_array[2][1])) stop(); + e_longint_unsigned_2d(&longint_unsigned_array[1][0][0]); + if (!check_2d(longint_unsigned_array[1])) stop(); + e_longint_unsigned_3d(&longint_unsigned_array[0][0][0]); + if (!check_3d(longint_unsigned_array)) stop(); + } + +#ifndef NO_TIME + { + svLogicVecVal time_array[4][3][2][2]; + e_time_0d(time_array[3][2][1]); + if (!check_0d(time_array[3][2][1], 64)) stop(); + e_time_1d(time_array[2][1][0]); + if (!check_1d(time_array[2][1], 64)) stop(); + e_time_2d(time_array[1][0][0]); + if (!check_2d(time_array[1], 64)) stop(); + e_time_3d(time_array[0][0][0]); + if (!check_3d(time_array, 64)) stop(); + } +#endif + +#ifndef NO_INTEGER + { + svLogicVecVal integer_array[4][3][2][1]; + e_integer_0d(integer_array[3][2][1]); + if (!check_0d(integer_array[3][2][1], 32)) stop(); + e_integer_1d(integer_array[2][1][0]); + if (!check_1d(integer_array[2][1], 32)) stop(); + e_integer_2d(integer_array[1][0][0]); + if (!check_2d(integer_array[1], 32)) stop(); + e_integer_3d(integer_array[0][0][0]); + if (!check_3d(integer_array, 32)) stop(); + } +#endif + + { + double real_array[4][3][2]; + e_real_0d(&real_array[3][2][1]); + if (!check_0d(real_array[3][2][1])) stop(); + e_real_1d(&real_array[2][1][0]); + if (!check_1d(real_array[2][1])) stop(); + e_real_2d(&real_array[1][0][0]); + if (!check_2d(real_array[1])) stop(); + e_real_3d(&real_array[0][0][0]); + if (!check_3d(real_array)) stop(); + } +#ifndef NO_SHORTREAL + { + float shortreal_array[4][3][2]; + e_shortreal_0d(&shortreal_array[3][2][1]); + if (!check_0d(shortreal_array[3][2][1])) stop(); + e_shortreal_1d(&shortreal_array[2][1][0]); + if (!check_1d(shortreal_array[2][1])) stop(); + e_shortreal_2d(&shortreal_array[1][0][0]); + if (!check_2d(shortreal_array[1])) stop(); + e_shortreal_3d(&shortreal_array[0][0][0]); + if (!check_3d(shortreal_array)) stop(); + } +#endif + + { + void* chandle_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) chandle_array[i][j][k] = NULL; + e_chandle_0d(&chandle_array[3][2][1]); + if (!chandle_array[3][2][1]) stop(); + e_chandle_1d(&chandle_array[2][1][0]); + if (!chandle_array[2][1][0]) stop(); + if (!chandle_array[2][1][1]) stop(); + e_chandle_2d(&chandle_array[1][0][0]); + if (!chandle_array[1][0][1]) stop(); + if (!chandle_array[1][1][1]) stop(); + if (!chandle_array[1][2][1]) stop(); + e_chandle_3d(&chandle_array[0][0][0]); + if (!chandle_array[0][0][0]) stop(); + if (!chandle_array[1][0][0]) stop(); + if (!chandle_array[2][0][0]) stop(); + if (!chandle_array[3][0][0]) stop(); + } + + { + const char* string_array[4][3][2]; + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) string_array[i][j][k] = NULL; + e_string_0d(&string_array[3][2][1]); + if (!compare(string_array[3][2][1], "42")) stop(); + e_string_1d(&string_array[2][1][0]); + if (!compare(string_array[2][1][0], "43")) stop(); + if (!compare(string_array[2][1][1], "44")) stop(); + e_string_2d(&string_array[1][0][0]); + if (!compare(string_array[1][0][1], "45")) stop(); + if (!compare(string_array[1][1][1], "46")) stop(); + if (!compare(string_array[1][2][1], "47")) stop(); + e_string_3d(&string_array[0][0][0]); + if (!compare(string_array[0][0][0], "48")) stop(); + if (!compare(string_array[1][0][0], "49")) stop(); + if (!compare(string_array[2][0][0], "50")) stop(); + if (!compare(string_array[3][0][0], "51")) stop(); + } + + { + svBitVecVal bit7_array[4][3][2][1]; + e_bit7_0d(bit7_array[3][2][1]); + if (!check_0d(bit7_array[3][2][1], 7)) stop(); + e_bit7_1d(bit7_array[2][1][0]); + if (!check_1d(bit7_array[2][1], 7)) stop(); + e_bit7_2d(bit7_array[1][0][0]); + if (!check_2d(bit7_array[1], 7)) stop(); + e_bit7_3d(bit7_array[0][0][0]); + if (!check_3d(bit7_array, 7)) stop(); + } + + { + svBitVecVal bit121_array[4][3][2][4]; + e_bit121_0d(bit121_array[3][2][1]); + if (!check_0d(bit121_array[3][2][1], 121)) stop(); + e_bit121_1d(bit121_array[2][1][0]); + if (!check_1d(bit121_array[2][1], 121)) stop(); + e_bit121_2d(bit121_array[1][0][0]); + if (!check_2d(bit121_array[1], 121)) stop(); + e_bit121_3d(bit121_array[0][0][0]); + if (!check_3d(bit121_array, 121)) stop(); + } + { + svLogicVecVal logic7_array[4][3][2][1]; + e_logic7_0d(logic7_array[3][2][1]); + if (!check_0d(logic7_array[3][2][1], 7)) stop(); + e_logic7_1d(logic7_array[2][1][0]); + if (!check_1d(logic7_array[2][1], 7)) stop(); + e_logic7_2d(logic7_array[1][0][0]); + if (!check_2d(logic7_array[1], 7)) stop(); + e_logic7_3d(logic7_array[0][0][0]); + if (!check_3d(logic7_array, 7)) stop(); + } + + { + svLogicVecVal logic121_array[4][3][2][4]; + e_logic121_0d(logic121_array[3][2][1]); + if (!check_0d(logic121_array[3][2][1], 121)) stop(); + e_logic121_1d(logic121_array[2][1][0]); + if (!check_1d(logic121_array[2][1], 121)) stop(); + e_logic121_2d(logic121_array[1][0][0]); + if (!check_2d(logic121_array[1], 121)) stop(); + e_logic121_3d(logic121_array[0][0][0]); + if (!check_3d(logic121_array, 121)) stop(); + } + + { + svLogicVecVal pack_struct_array[4][3][2][1]; + e_pack_struct_0d(pack_struct_array[3][2][1]); + if (!check_0d(pack_struct_array[3][2][1], 7)) stop(); + e_pack_struct_1d(pack_struct_array[2][1][0]); + if (!check_1d(pack_struct_array[2][1], 7)) stop(); + e_pack_struct_2d(pack_struct_array[1][0][0]); + if (!check_2d(pack_struct_array[1], 7)) stop(); + e_pack_struct_3d(pack_struct_array[0][0][0]); + if (!check_3d(pack_struct_array, 7)) stop(); + } + +#ifndef NO_UNPACK_STRUCT + { + unpack_struct_t unpack_struct_array[4][3][2]; + e_unpack_struct_0d(&unpack_struct_array[3][2][1]); + if (!compare(unpack_struct_array[3][2][1].val, 42, 121)) stop(); + e_unpack_struct_1d(&unpack_struct_array[2][1][0]); + if (!compare(unpack_struct_array[2][1][0].val, 43, 121)) stop(); + if (!compare(unpack_struct_array[2][1][1].val, 44, 121)) stop(); + e_unpack_struct_2d(&unpack_struct_array[1][0][0]); + if (!compare(unpack_struct_array[1][0][1].val, 45, 121)) stop(); + if (!compare(unpack_struct_array[1][1][1].val, 46, 121)) stop(); + if (!compare(unpack_struct_array[1][2][1].val, 47, 121)) stop(); + e_unpack_struct_3d(&unpack_struct_array[0][0][0]); + if (!compare(unpack_struct_array[0][0][0].val, 48, 121)) stop(); + if (!compare(unpack_struct_array[1][0][0].val, 49, 121)) stop(); + if (!compare(unpack_struct_array[2][0][0].val, 50, 121)) stop(); + if (!compare(unpack_struct_array[3][0][0].val, 51, 121)) stop(); + } +#endif +} diff --git a/test_regress/t/t_dpi_arg_output_unpack.pl b/test_regress/t/t_dpi_arg_output_unpack.pl new file mode 100755 index 000000000..4a2f325ab --- /dev/null +++ b/test_regress/t/t_dpi_arg_output_unpack.pl @@ -0,0 +1,44 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 by Geza Lore. This program is free software; you can +# redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +if ($Self->{nc}) { + # For NC, compile twice, first just to generate DPI headers + compile( + nc_flags2 => ["+ncdpiheader+$Self->{obj_dir}/dpi-exp.h", + "+ncdpiimpheader+$Self->{obj_dir}/dpi-imp.h"] + ); +} + +compile( + v_flags2 => ["t/t_dpi_arg_output_unpack.cpp"], + verilator_flags2 => ["-Wall -Wno-DECLFILENAME"], + # NC: Gdd the obj_dir to the C include path + nc_flags2 => ["+ncscargs+-I$Self->{obj_dir}"], + # ModelSim: Generate DPI header, add obj_dir to the C include path + ms_flags2 => ["-dpiheader $Self->{obj_dir}/dpi.h", + "-ccflags -I$Self->{obj_dir}"], + ); + +if ($Self->{vlt_all}) { + files_identical( + "$Self->{obj_dir}/Vt_dpi_arg_output_unpack__Dpi.h", + "t/t_dpi_arg_output_unpack__Dpi.out" + ); +} + +execute( + check_finished => 1, + ms_pli => 0 + ); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_arg_output_unpack.v b/test_regress/t/t_dpi_arg_output_unpack.v new file mode 100644 index 000000000..f2fbcd7ee --- /dev/null +++ b/test_regress/t/t_dpi_arg_output_unpack.v @@ -0,0 +1,761 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +`ifdef VCS + `define NO_TIME +`endif + +`ifdef NC + `define NO_TIME + `define NO_INTEGER + `define NO_SHORTREAL +`endif + +`ifdef MS +`endif + +`ifdef VERILATOR + `define NO_SHORTREAL + `define NO_UNPACK_STRUCT + `define NULL 64'd0 +`else + `define NULL null +`endif + +`define CHECK_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":", (act), " as expected"); \ + end else begin \ + $display("Mismatch %s expected:%d actual:%d at %d", `"act`", \ + int'(exp), \ + int'(act), `__LINE__); \ + $stop; \ + end + +`define CHECK_0D(val) `CHECK_VAL((val), 42) +`define CHECK_1D(val) `CHECK_VAL(val[0], 43); \ +`CHECK_VAL(val[1], 44) +`define CHECK_2D(val) `CHECK_VAL(val[0][1], 45); \ +`CHECK_VAL(val[1][1], 46); \ +`CHECK_VAL(val[2][1], 47) +`define CHECK_3D(val) `CHECK_VAL(val[0][0][0], 48); \ +`CHECK_VAL(val[1][0][0], 49); \ +`CHECK_VAL(val[2][0][0], 50); \ +`CHECK_VAL(val[3][0][0], 51) + +`define CHECK_CHANDLE_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":non-null as expected"); \ + end else begin \ + $display("Mismatch %s expected:%s but %s at %d", `"act`", \ + (exp) ? "null" : "non-null", (act) ? "null" : "non-null", `__LINE__); \ + $stop; \ + end + +`define CHECK_STRING_VAL(act, exp) if ((act) == (exp)) begin \ + if (ENABLE_VERBOSE_MESSAGE)$display(`"act`", ":", (act), " as expected"); \ + end else begin \ + $display("Mismatch %s expected:%s actual:%s at %d", \ + `"act`", (exp), (act), `__LINE__); \ + $stop; \ + end + +`define SET_VALUES(val) \ +val[3][2][1] = 42; \ +val[2][1][0] = 43; val[2][1][1] = 44; \ +val[1][0][1] = 45; val[1][1][1] = 46; val[1][2][1] = 47; \ +val[0][0][0] = 48; val[1][0][0] = 49; val[2][0][0] = 50; val[3][0][0] = 51 + +module t; + + localparam ENABLE_VERBOSE_MESSAGE = 0; + + // Legal output argument types for DPI functions + + //====================================================================== + // Type definitions + //====================================================================== + + typedef byte byte_array_t[4][3][2]; + typedef byte unsigned byte_unsigned_array_t[4][3][2]; + typedef shortint shortint_array_t[4][3][2]; + typedef shortint unsigned shortint_unsigned_array_t[4][3][2]; + typedef int int_array_t[4][3][2]; + typedef int unsigned int_unsigned_array_t[4][3][2]; + typedef longint longint_array_t[4][3][2]; + typedef longint unsigned longint_unsigned_array_t[4][3][2]; +`ifndef NO_TIME + typedef time time_array_t[4][3][2]; +`endif +`ifndef NO_INTEGER + typedef integer integer_array_t[4][3][2]; +`endif + typedef real real_array_t[4][3][2]; +`ifndef NO_SHORTREAL + typedef shortreal shortreal_array_t[4][3][2]; +`endif + typedef chandle chandle_array_t[4][3][2]; + typedef string string_array_t[4][3][2]; + typedef bit [6:0] bit7_array_t[4][3][2]; + typedef bit [120:0] bit121_array_t[4][3][2]; + typedef logic [6:0] logic7_array_t[4][3][2]; + typedef logic [120:0] logic121_array_t[4][3][2]; + + typedef struct packed { + logic [6:0] val; + } pack_struct_t; + typedef pack_struct_t pack_struct_array_t[4][3][2]; +`ifndef NO_UNPACK_STRUCT + typedef struct { + logic [120:0] val; + } unpack_struct_t; + typedef unpack_struct_t unpack_struct_array_t[4][3][2]; +`endif + + //====================================================================== + // Imports + //====================================================================== + + // Returns non-null pointer + import "DPI-C" function chandle get_non_null(); + + import "DPI-C" function void i_byte_0d(output byte val); + import "DPI-C" function void i_byte_1d(output byte val[2]); + import "DPI-C" function void i_byte_2d(output byte val[3][2]); + import "DPI-C" function void i_byte_3d(output byte_array_t val); + + import "DPI-C" function void i_byte_unsigned_0d(output byte unsigned val); + import "DPI-C" function void i_byte_unsigned_1d(output byte unsigned val[2]); + import "DPI-C" function void i_byte_unsigned_2d(output byte unsigned val[3][2]); + import "DPI-C" function void i_byte_unsigned_3d(output byte_unsigned_array_t val); + + import "DPI-C" function void i_shortint_0d(output shortint val); + import "DPI-C" function void i_shortint_1d(output shortint val[2]); + import "DPI-C" function void i_shortint_2d(output shortint val[3][2]); + import "DPI-C" function void i_shortint_3d(output shortint_array_t val); + + import "DPI-C" function void i_shortint_unsigned_0d(output shortint unsigned val); + import "DPI-C" function void i_shortint_unsigned_1d(output shortint unsigned val[2]); + import "DPI-C" function void i_shortint_unsigned_2d(output shortint unsigned val[3][2]); + import "DPI-C" function void i_shortint_unsigned_3d(output shortint_unsigned_array_t val); + + import "DPI-C" function void i_int_0d(output int val); + import "DPI-C" function void i_int_1d(output int val[2]); + import "DPI-C" function void i_int_2d(output int val[3][2]); + import "DPI-C" function void i_int_3d(output int_array_t val); + + import "DPI-C" function void i_int_unsigned_0d(output int unsigned val); + import "DPI-C" function void i_int_unsigned_1d(output int unsigned val[2]); + import "DPI-C" function void i_int_unsigned_2d(output int unsigned val[3][2]); + import "DPI-C" function void i_int_unsigned_3d(output int_unsigned_array_t val); + + import "DPI-C" function void i_longint_0d(output longint val); + import "DPI-C" function void i_longint_1d(output longint val[2]); + import "DPI-C" function void i_longint_2d(output longint val[3][2]); + import "DPI-C" function void i_longint_3d(output longint_array_t val); + + import "DPI-C" function void i_longint_unsigned_0d(output longint unsigned val); + import "DPI-C" function void i_longint_unsigned_1d(output longint unsigned val[2]); + import "DPI-C" function void i_longint_unsigned_2d(output longint unsigned val[3][2]); + import "DPI-C" function void i_longint_unsigned_3d(output longint_unsigned_array_t val); + +`ifndef NO_TIME + import "DPI-C" function void i_time_0d(output time val); + import "DPI-C" function void i_time_1d(output time val[2]); + import "DPI-C" function void i_time_2d(output time val[3][2]); + import "DPI-C" function void i_time_3d(output time_array_t val); +`endif + +`ifndef NO_INTEGER + import "DPI-C" function void i_integer_0d(output integer val); + import "DPI-C" function void i_integer_1d(output integer val[2]); + import "DPI-C" function void i_integer_2d(output integer val[3][2]); + import "DPI-C" function void i_integer_3d(output integer_array_t val); +`endif + + import "DPI-C" function void i_real_0d(output real val); + import "DPI-C" function void i_real_1d(output real val[2]); + import "DPI-C" function void i_real_2d(output real val[3][2]); + import "DPI-C" function void i_real_3d(output real_array_t val); + +`ifndef NO_SHORTREAL + import "DPI-C" function void i_shortreal_0d(output shortreal val); + import "DPI-C" function void i_shortreal_1d(output shortreal val[2]); + import "DPI-C" function void i_shortreal_2d(output shortreal val[3][2]); + import "DPI-C" function void i_shortreal_3d(output shortreal_array_t val); +`endif + + import "DPI-C" function void i_chandle_0d(output chandle val); + import "DPI-C" function void i_chandle_1d(output chandle val[2]); + import "DPI-C" function void i_chandle_2d(output chandle val[3][2]); + import "DPI-C" function void i_chandle_3d(output chandle_array_t val); + + import "DPI-C" function void i_string_0d(output string val); + import "DPI-C" function void i_string_1d(output string val[2]); + import "DPI-C" function void i_string_2d(output string val[3][2]); + import "DPI-C" function void i_string_3d(output string_array_t val); + + import "DPI-C" function void i_bit7_0d(output bit[6:0] val); + import "DPI-C" function void i_bit7_1d(output bit[6:0] val[2]); + import "DPI-C" function void i_bit7_2d(output bit[6:0] val[3][2]); + import "DPI-C" function void i_bit7_3d(output bit7_array_t val); + + import "DPI-C" function void i_bit121_0d(output bit[120:0] val); + import "DPI-C" function void i_bit121_1d(output bit[120:0] val[2]); + import "DPI-C" function void i_bit121_2d(output bit[120:0] val[3][2]); + import "DPI-C" function void i_bit121_3d(output bit121_array_t val); + + import "DPI-C" function void i_logic7_0d(output logic[6:0] val); + import "DPI-C" function void i_logic7_1d(output logic[6:0] val[2]); + import "DPI-C" function void i_logic7_2d(output logic[6:0] val[3][2]); + import "DPI-C" function void i_logic7_3d(output logic7_array_t val); + + import "DPI-C" function void i_logic121_0d(output logic[120:0] val); + import "DPI-C" function void i_logic121_1d(output logic[120:0] val[2]); + import "DPI-C" function void i_logic121_2d(output logic[120:0] val[3][2]); + import "DPI-C" function void i_logic121_3d(output logic121_array_t val); + + import "DPI-C" function void i_pack_struct_0d(output pack_struct_t val); + import "DPI-C" function void i_pack_struct_1d(output pack_struct_t val[2]); + import "DPI-C" function void i_pack_struct_2d(output pack_struct_t val[3][2]); + import "DPI-C" function void i_pack_struct_3d(output pack_struct_array_t val); + +`ifndef NO_UNPACK_STRUCT + import "DPI-C" function void i_unpack_struct_0d(output unpack_struct_t val); + import "DPI-C" function void i_unpack_struct_1d(output unpack_struct_t val[2]); + import "DPI-C" function void i_unpack_struct_2d(output unpack_struct_t val[3][2]); + import "DPI-C" function void i_unpack_struct_3d(output unpack_struct_array_t val); +`endif + + //====================================================================== + // Exports + //====================================================================== + export "DPI-C" function e_byte_0d; + export "DPI-C" function e_byte_1d; + export "DPI-C" function e_byte_2d; + export "DPI-C" function e_byte_3d; + + export "DPI-C" function e_byte_unsigned_0d; + export "DPI-C" function e_byte_unsigned_1d; + export "DPI-C" function e_byte_unsigned_2d; + export "DPI-C" function e_byte_unsigned_3d; + + export "DPI-C" function e_shortint_0d; + export "DPI-C" function e_shortint_1d; + export "DPI-C" function e_shortint_2d; + export "DPI-C" function e_shortint_3d; + + export "DPI-C" function e_shortint_unsigned_0d; + export "DPI-C" function e_shortint_unsigned_1d; + export "DPI-C" function e_shortint_unsigned_2d; + export "DPI-C" function e_shortint_unsigned_3d; + + export "DPI-C" function e_int_0d; + export "DPI-C" function e_int_1d; + export "DPI-C" function e_int_2d; + export "DPI-C" function e_int_3d; + + export "DPI-C" function e_int_unsigned_0d; + export "DPI-C" function e_int_unsigned_1d; + export "DPI-C" function e_int_unsigned_2d; + export "DPI-C" function e_int_unsigned_3d; + + export "DPI-C" function e_longint_0d; + export "DPI-C" function e_longint_1d; + export "DPI-C" function e_longint_2d; + export "DPI-C" function e_longint_3d; + + export "DPI-C" function e_longint_unsigned_0d; + export "DPI-C" function e_longint_unsigned_1d; + export "DPI-C" function e_longint_unsigned_2d; + export "DPI-C" function e_longint_unsigned_3d; + +`ifndef NO_TIME + export "DPI-C" function e_time_0d; + export "DPI-C" function e_time_1d; + export "DPI-C" function e_time_2d; + export "DPI-C" function e_time_3d; +`endif + +`ifndef NO_INTEGER + export "DPI-C" function e_integer_0d; + export "DPI-C" function e_integer_1d; + export "DPI-C" function e_integer_2d; + export "DPI-C" function e_integer_3d; +`endif + + export "DPI-C" function e_real_0d; + export "DPI-C" function e_real_1d; + export "DPI-C" function e_real_2d; + export "DPI-C" function e_real_3d; + +`ifndef NO_SHORTREAL + export "DPI-C" function e_shortreal_0d; + export "DPI-C" function e_shortreal_1d; + export "DPI-C" function e_shortreal_2d; + export "DPI-C" function e_shortreal_3d; +`endif + + export "DPI-C" function e_chandle_0d; + export "DPI-C" function e_chandle_1d; + export "DPI-C" function e_chandle_2d; + export "DPI-C" function e_chandle_3d; + + export "DPI-C" function e_string_0d; + export "DPI-C" function e_string_1d; + export "DPI-C" function e_string_2d; + export "DPI-C" function e_string_3d; + + export "DPI-C" function e_bit7_0d; + export "DPI-C" function e_bit7_1d; + export "DPI-C" function e_bit7_2d; + export "DPI-C" function e_bit7_3d; + + export "DPI-C" function e_bit121_0d; + export "DPI-C" function e_bit121_1d; + export "DPI-C" function e_bit121_2d; + export "DPI-C" function e_bit121_3d; + + export "DPI-C" function e_logic7_0d; + export "DPI-C" function e_logic7_1d; + export "DPI-C" function e_logic7_2d; + export "DPI-C" function e_logic7_3d; + + export "DPI-C" function e_logic121_0d; + export "DPI-C" function e_logic121_1d; + export "DPI-C" function e_logic121_2d; + export "DPI-C" function e_logic121_3d; + + export "DPI-C" function e_pack_struct_0d; + export "DPI-C" function e_pack_struct_1d; + export "DPI-C" function e_pack_struct_2d; + export "DPI-C" function e_pack_struct_3d; + +`ifndef NO_UNPACK_STRUCT + export "DPI-C" function e_unpack_struct_0d; + export "DPI-C" function e_unpack_struct_1d; + export "DPI-C" function e_unpack_struct_2d; + export "DPI-C" function e_unpack_struct_3d; +`endif + //====================================================================== + // Definitions of exported functions + //====================================================================== +`define SET_0D(val) val = 42 +`define SET_1D(val) val[0] = 43; val[1] = 44 +`define SET_2D(val) val[0][1] = 45; val[1][1] = 46; val[2][1] = 47 +`define SET_3D(val) val[0][0][0] = 48; val[1][0][0] = 49; val[2][0][0] = 50; val[3][0][0] = 51 + + function void e_byte_0d(output byte val); `SET_0D(val); endfunction + function void e_byte_1d(output byte val[2]); `SET_1D(val); endfunction + function void e_byte_2d(output byte val[3][2]); `SET_2D(val); endfunction + function void e_byte_3d(output byte_array_t val); `SET_3D(val); endfunction + + function void e_byte_unsigned_0d(output byte unsigned val); `SET_0D(val); endfunction + function void e_byte_unsigned_1d(output byte unsigned val[2]); `SET_1D(val); endfunction + function void e_byte_unsigned_2d(output byte unsigned val[3][2]); `SET_2D(val); endfunction + function void e_byte_unsigned_3d(output byte_unsigned_array_t val); `SET_3D(val); endfunction + + function void e_shortint_0d(output shortint val); `SET_0D(val); endfunction + function void e_shortint_1d(output shortint val[2]); `SET_1D(val); endfunction + function void e_shortint_2d(output shortint val[3][2]); `SET_2D(val); endfunction + function void e_shortint_3d(output shortint_array_t val); `SET_3D(val); endfunction + + function void e_shortint_unsigned_0d(output shortint unsigned val); `SET_0D(val); endfunction + function void e_shortint_unsigned_1d(output shortint unsigned val[2]); `SET_1D(val); endfunction + function void e_shortint_unsigned_2d(output shortint unsigned val[3][2]); `SET_2D(val); endfunction + function void e_shortint_unsigned_3d(output shortint_unsigned_array_t val); `SET_3D(val); endfunction + + function void e_int_0d(output int val); `SET_0D(val); endfunction + function void e_int_1d(output int val[2]); `SET_1D(val); endfunction + function void e_int_2d(output int val[3][2]); `SET_2D(val); endfunction + function void e_int_3d(output int_array_t val); `SET_3D(val); endfunction + + function void e_int_unsigned_0d(output int unsigned val); `SET_0D(val); endfunction + function void e_int_unsigned_1d(output int unsigned val[2]); `SET_1D(val); endfunction + function void e_int_unsigned_2d(output int unsigned val[3][2]); `SET_2D(val); endfunction + function void e_int_unsigned_3d(output int_unsigned_array_t val); `SET_3D(val); endfunction + + function void e_longint_0d(output longint val); `SET_0D(val); endfunction + function void e_longint_1d(output longint val[2]); `SET_1D(val); endfunction + function void e_longint_2d(output longint val[3][2]); `SET_2D(val); endfunction + function void e_longint_3d(output longint_array_t val); `SET_3D(val); endfunction + + function void e_longint_unsigned_0d(output longint unsigned val); `SET_0D(val); endfunction + function void e_longint_unsigned_1d(output longint unsigned val[2]); `SET_1D(val); endfunction + function void e_longint_unsigned_2d(output longint unsigned val[3][2]); `SET_2D(val); endfunction + function void e_longint_unsigned_3d(output longint_unsigned_array_t val); `SET_3D(val); endfunction + +`ifndef NO_TIME + function void e_time_0d(output time val); `SET_0D(val); endfunction + function void e_time_1d(output time val[2]); `SET_1D(val); endfunction + function void e_time_2d(output time val[3][2]); `SET_2D(val); endfunction + function void e_time_3d(output time_array_t val); `SET_3D(val); endfunction +`endif + +`ifndef NO_INTEGER + function void e_integer_0d(output integer val); `SET_0D(val); endfunction + function void e_integer_1d(output integer val[2]); `SET_1D(val); endfunction + function void e_integer_2d(output integer val[3][2]); `SET_2D(val); endfunction + function void e_integer_3d(output integer_array_t val); `SET_3D(val); endfunction +`endif + + function void e_real_0d(output real val); `SET_0D(val); endfunction + function void e_real_1d(output real val[2]); `SET_1D(val); endfunction + function void e_real_2d(output real val[3][2]); `SET_2D(val); endfunction + function void e_real_3d(output real_array_t val); `SET_3D(val); endfunction + +`ifndef NO_SHORTREAL + function void e_shortreal_0d(output shortreal val); `SET_0D(val); endfunction + function void e_shortreal_1d(output shortreal val[2]); `SET_1D(val); endfunction + function void e_shortreal_2d(output shortreal val[3][2]); `SET_2D(val); endfunction + function void e_shortreal_3d(output shortreal_array_t val); `SET_3D(val); endfunction +`endif + + function void e_chandle_0d(output chandle val); + val = get_non_null(); + endfunction + function void e_chandle_1d(output chandle val[2]); + val[0] = get_non_null(); + val[1] = get_non_null(); + endfunction + function void e_chandle_2d(output chandle val[3][2]); + val[0][1] = get_non_null(); + val[1][1] = get_non_null(); + val[2][1] = get_non_null(); + endfunction + function void e_chandle_3d(output chandle_array_t val); + val[0][0][0] = get_non_null(); + val[1][0][0] = get_non_null(); + val[2][0][0] = get_non_null(); + val[3][0][0] = get_non_null(); + endfunction + + function void e_string_0d(output string val); + val = "42"; + endfunction + function void e_string_1d(output string val[2]); + val[0] = "43"; + val[1] = "44"; + endfunction + function void e_string_2d(output string val[3][2]); + val[0][1] = "45"; + val[1][1] = "46"; + val[2][1] = "47"; + endfunction + function void e_string_3d(output string_array_t val); + val[0][0][0] = "48"; + val[1][0][0] = "49"; + val[2][0][0] = "50"; + val[3][0][0] = "51"; + endfunction + + function void e_bit7_0d(output bit[6:0] val); `SET_0D(val); endfunction + function void e_bit7_1d(output bit[6:0] val[2]); `SET_1D(val); endfunction + function void e_bit7_2d(output bit[6:0] val[3][2]); `SET_2D(val); endfunction + function void e_bit7_3d(output bit7_array_t val); `SET_3D(val); endfunction + + function void e_bit121_0d(output bit[120:0] val); `SET_0D(val); endfunction + function void e_bit121_1d(output bit[120:0] val[2]); `SET_1D(val); endfunction + function void e_bit121_2d(output bit[120:0] val[3][2]); `SET_2D(val); endfunction + function void e_bit121_3d(output bit121_array_t val); `SET_3D(val); endfunction + + function void e_logic7_0d(output logic[6:0] val); `SET_0D(val); endfunction + function void e_logic7_1d(output logic[6:0] val[2]); `SET_1D(val); endfunction + function void e_logic7_2d(output logic[6:0] val[3][2]); `SET_2D(val); endfunction + function void e_logic7_3d(output logic7_array_t val); `SET_3D(val); endfunction + + function void e_logic121_0d(output logic[120:0] val); `SET_0D(val); endfunction + function void e_logic121_1d(output logic[120:0] val[2]); `SET_1D(val); endfunction + function void e_logic121_2d(output logic[120:0] val[3][2]); `SET_2D(val); endfunction + function void e_logic121_3d(output logic121_array_t val); `SET_3D(val); endfunction + + function void e_pack_struct_0d(output pack_struct_t val); `SET_0D(val); endfunction + function void e_pack_struct_1d(output pack_struct_t val[2]); `SET_1D(val); endfunction + function void e_pack_struct_2d(output pack_struct_t val[3][2]); `SET_2D(val); endfunction + function void e_pack_struct_3d(output pack_struct_array_t val); `SET_3D(val); endfunction + +`ifndef NO_UNPACK_STRUCT + function void e_unpack_struct_0d(output unpack_struct_t val); + val.val = 42; + endfunction + function void e_unpack_struct_1d(output unpack_struct_t val[2]); + val[0].val = 43; + val[1].val = 44; + endfunction + function void e_unpack_struct_2d(output unpack_struct_t val[3][2]); + val[0][1].val = 45; + val[1][1].val = 46; + val[2][1].val = 47; + endfunction + function void e_unpack_struct_3d(output unpack_struct_array_t val); + val[0][0][0].val = 48; + val[1][0][0].val = 49; + val[2][0][0].val = 50; + val[3][0][0].val = 51; + endfunction +`endif + + //====================================================================== + // Invoke all imported functions + //====================================================================== + + import "DPI-C" context function void check_exports(); + + initial begin + byte_array_t byte_array; + byte_unsigned_array_t byte_unsigned_array; + shortint_array_t shortint_array; + shortint_unsigned_array_t shortint_unsigned_array; + int_array_t int_array; + int_unsigned_array_t int_unsigned_array; + longint_array_t longint_array; + longint_unsigned_array_t longint_unsigned_array; +`ifndef NO_TIME + time_array_t time_array; +`endif +`ifndef NO_INTEGER + integer_array_t integer_array; +`endif + real_array_t real_array; +`ifndef NO_SHORTREAL + shortreal_array_t shortreal_array; +`endif + chandle_array_t chandle_array; + string_array_t string_array; + bit7_array_t bit7_array; + bit121_array_t bit121_array; + logic7_array_t logic7_array; + logic121_array_t logic121_array; + pack_struct_array_t pack_struct_array; +`ifndef NO_UNPACK_STRUCT + unpack_struct_array_t unpack_struct_array; +`endif + + i_byte_0d(byte_array[3][2][1]); + `CHECK_0D(byte_array[3][2][1]); + i_byte_1d(byte_array[2][1]); + `CHECK_1D(byte_array[2][1]); + i_byte_2d(byte_array[1]); + `CHECK_2D(byte_array[1]); + i_byte_3d(byte_array); + `CHECK_3D(byte_array); + + i_byte_unsigned_0d(byte_unsigned_array[3][2][1]); + `CHECK_0D(byte_unsigned_array[3][2][1]); + i_byte_unsigned_1d(byte_unsigned_array[2][1]); + `CHECK_1D(byte_unsigned_array[2][1]); + i_byte_unsigned_2d(byte_unsigned_array[1]); + `CHECK_2D(byte_unsigned_array[1]); + i_byte_unsigned_3d(byte_unsigned_array); + `CHECK_3D(byte_unsigned_array); + + i_shortint_0d(shortint_array[3][2][1]); + `CHECK_0D(shortint_array[3][2][1]); + i_shortint_1d(shortint_array[2][1]); + `CHECK_1D(shortint_array[2][1]); + i_shortint_2d(shortint_array[1]); + `CHECK_2D(shortint_array[1]); + i_shortint_3d(shortint_array); + `CHECK_3D(shortint_array); + + i_shortint_unsigned_0d(shortint_unsigned_array[3][2][1]); + `CHECK_0D(shortint_unsigned_array[3][2][1]); + i_shortint_unsigned_1d(shortint_unsigned_array[2][1]); + `CHECK_1D(shortint_unsigned_array[2][1]); + i_shortint_unsigned_2d(shortint_unsigned_array[1]); + `CHECK_2D(shortint_unsigned_array[1]); + i_shortint_unsigned_3d(shortint_unsigned_array); + `CHECK_3D(shortint_unsigned_array); + + i_int_0d(int_array[3][2][1]); + `CHECK_0D(int_array[3][2][1]); + i_int_1d(int_array[2][1]); + `CHECK_1D(int_array[2][1]); + i_int_2d(int_array[1]); + `CHECK_2D(int_array[1]); + i_int_3d(int_array); + `CHECK_3D(int_array); + + i_int_unsigned_0d(int_unsigned_array[3][2][1]); + `CHECK_0D(int_unsigned_array[3][2][1]); + i_int_unsigned_1d(int_unsigned_array[2][1]); + `CHECK_1D(int_unsigned_array[2][1]); + i_int_unsigned_2d(int_unsigned_array[1]); + `CHECK_2D(int_unsigned_array[1]); + i_int_unsigned_3d(int_unsigned_array); + `CHECK_3D(int_unsigned_array); + + i_longint_0d(longint_array[3][2][1]); + `CHECK_0D(longint_array[3][2][1]); + i_longint_1d(longint_array[2][1]); + `CHECK_1D(longint_array[2][1]); + i_longint_2d(longint_array[1]); + `CHECK_2D(longint_array[1]); + i_longint_3d(longint_array); + `CHECK_3D(longint_array); + + i_longint_unsigned_0d(longint_unsigned_array[3][2][1]); + `CHECK_0D(longint_unsigned_array[3][2][1]); + i_longint_unsigned_1d(longint_unsigned_array[2][1]); + `CHECK_1D(longint_unsigned_array[2][1]); + i_longint_unsigned_2d(longint_unsigned_array[1]); + `CHECK_2D(longint_unsigned_array[1]); + i_longint_unsigned_3d(longint_unsigned_array); + `CHECK_3D(longint_unsigned_array); + +`ifndef NO_TIME + i_time_0d(time_array[3][2][1]); + `CHECK_0D(time_array[3][2][1]); + i_time_1d(time_array[2][1]); + `CHECK_1D(time_array[2][1]); + i_time_2d(time_array[1]); + `CHECK_2D(time_array[1]); + i_time_3d(time_array); + `CHECK_3D(time_array); +`endif + +`ifndef NO_INTEGER + i_integer_0d(integer_array[3][2][1]); + `CHECK_0D(integer_array[3][2][1]); + i_integer_1d(integer_array[2][1]); + `CHECK_1D(integer_array[2][1]); + i_integer_2d(integer_array[1]); + `CHECK_2D(integer_array[1]); + i_integer_3d(integer_array); + `CHECK_3D(integer_array); +`endif + + i_real_0d(real_array[3][2][1]); + `CHECK_0D(real_array[3][2][1]); + i_real_1d(real_array[2][1]); + `CHECK_1D(real_array[2][1]); + i_real_2d(real_array[1]); + `CHECK_2D(real_array[1]); + i_real_3d(real_array); + `CHECK_3D(real_array); + +`ifndef NO_SHORTREAL + i_shortreal_0d(shortreal_array[3][2][1]); + `CHECK_0D(shortreal_array[3][2][1]); + i_shortreal_1d(shortreal_array[2][1]); + `CHECK_1D(shortreal_array[2][1]); + i_shortreal_2d(shortreal_array[1]); + `CHECK_2D(shortreal_array[1]); + i_shortreal_3d(shortreal_array); + `CHECK_3D(shortreal_array); +`endif + + for (int i = 0; i < 4; ++i) + for (int j = 0; j < 3; ++j) + for (int k = 0; k < 2; ++k) + chandle_array[i][j][k] = null; + i_chandle_0d(chandle_array[3][2][1]); + `CHECK_CHANDLE_VAL(chandle_array[3][2][1], get_non_null()); + i_chandle_1d(chandle_array[2][1]); + `CHECK_CHANDLE_VAL(chandle_array[2][1][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[2][1][1], get_non_null()); + i_chandle_2d(chandle_array[1]); + `CHECK_CHANDLE_VAL(chandle_array[1][0][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][1][1], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][2][1], get_non_null()); + i_chandle_3d(chandle_array); + `CHECK_CHANDLE_VAL(chandle_array[0][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[1][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[2][0][0], get_non_null()); + `CHECK_CHANDLE_VAL(chandle_array[3][0][0], get_non_null()); + + i_string_0d(string_array[3][2][1]); + `CHECK_STRING_VAL(string_array[3][2][1], "42"); + i_string_1d(string_array[2][1]); + `CHECK_STRING_VAL(string_array[2][1][0], "43"); + `CHECK_STRING_VAL(string_array[2][1][1], "44"); + i_string_2d(string_array[1]); + `CHECK_STRING_VAL(string_array[1][0][1], "45"); + `CHECK_STRING_VAL(string_array[1][1][1], "46"); + `CHECK_STRING_VAL(string_array[1][2][1], "47"); + i_string_3d(string_array); + `CHECK_STRING_VAL(string_array[0][0][0], "48"); + `CHECK_STRING_VAL(string_array[1][0][0], "49"); + `CHECK_STRING_VAL(string_array[2][0][0], "50"); + `CHECK_STRING_VAL(string_array[3][0][0], "51"); + + i_bit7_0d(bit7_array[3][2][1]); + `CHECK_0D(bit7_array[3][2][1]); + i_bit7_1d(bit7_array[2][1]); + `CHECK_1D(bit7_array[2][1]); + i_bit7_2d(bit7_array[1]); + `CHECK_2D(bit7_array[1]); + i_bit7_3d(bit7_array); + `CHECK_3D(bit7_array); + + i_bit121_0d(bit121_array[3][2][1]); + `CHECK_0D(bit121_array[3][2][1]); + i_bit121_1d(bit121_array[2][1]); + `CHECK_1D(bit121_array[2][1]); + i_bit121_2d(bit121_array[1]); + `CHECK_2D(bit121_array[1]); + i_bit121_3d(bit121_array); + `CHECK_3D(bit121_array); + + i_logic7_0d(logic7_array[3][2][1]); + `CHECK_0D(logic7_array[3][2][1]); + i_logic7_1d(logic7_array[2][1]); + `CHECK_1D(logic7_array[2][1]); + i_logic7_2d(logic7_array[1]); + `CHECK_2D(logic7_array[1]); + i_logic7_3d(logic7_array); + `CHECK_3D(logic7_array); + + i_logic121_0d(logic121_array[3][2][1]); + `CHECK_0D(logic121_array[3][2][1]); + i_logic121_1d(logic121_array[2][1]); + `CHECK_1D(logic121_array[2][1]); + i_logic121_2d(logic121_array[1]); + `CHECK_2D(logic121_array[1]); + i_logic121_3d(logic121_array); + `CHECK_3D(logic121_array); + + i_pack_struct_0d(pack_struct_array[3][2][1]); + `CHECK_0D(pack_struct_array[3][2][1]); + i_pack_struct_1d(pack_struct_array[2][1]); + `CHECK_1D(pack_struct_array[2][1]); + i_pack_struct_2d(pack_struct_array[1]); + `CHECK_2D(pack_struct_array[1]); + i_pack_struct_3d(pack_struct_array); + `CHECK_3D(pack_struct_array); + + `SET_VALUES(pack_struct_array); + i_pack_struct_0d(pack_struct_array[3][2][1]); + i_pack_struct_1d(pack_struct_array[2][1]); + i_pack_struct_2d(pack_struct_array[1]); + i_pack_struct_3d(pack_struct_array); + +`ifndef NO_UNPACK_STRUCT + i_unpack_struct_0d(unpack_struct_array[3][2][1]); + `CHECK_VAL(unpack_struct_array[3][2][1].val, 42); + + i_unpack_struct_1d(unpack_struct_array[2][1]); + `CHECK_VAL(unpack_struct_array[2][1][0].val, 43); + `CHECK_VAL(unpack_struct_array[2][1][1].val, 44); + + i_unpack_struct_2d(unpack_struct_array[1]); + `CHECK_VAL(unpack_struct_array[1][0][1].val, 45); + `CHECK_VAL(unpack_struct_array[1][1][1].val, 46); + `CHECK_VAL(unpack_struct_array[1][2][1].val, 47); + + i_unpack_struct_3d(unpack_struct_array); + `CHECK_VAL(unpack_struct_array[0][0][0].val, 48); + `CHECK_VAL(unpack_struct_array[1][0][0].val, 49); + `CHECK_VAL(unpack_struct_array[2][0][0].val, 50); + `CHECK_VAL(unpack_struct_array[3][0][0].val, 51); +`endif + + check_exports(); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_dpi_arg_output_unpack__Dpi.out b/test_regress/t/t_dpi_arg_output_unpack__Dpi.out new file mode 100644 index 000000000..0c038cb14 --- /dev/null +++ b/test_regress/t/t_dpi_arg_output_unpack__Dpi.out @@ -0,0 +1,313 @@ +// Verilated -*- C++ -*- +// DESCRIPTION: Verilator output: Prototypes for DPI import and export functions. +// +// Verilator includes this file in all generated .cpp files that use DPI functions. +// Manually include this file where DPI .c import functions are declared to ensure +// the C functions match the expectations of the DPI imports. + +#include "svdpi.h" + +#ifdef __cplusplus +extern "C" { +#endif + + + // DPI EXPORTS + // DPI export at t/t_dpi_arg_output_unpack.v:460:18 + extern void e_bit121_0d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:461:18 + extern void e_bit121_1d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:462:18 + extern void e_bit121_2d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:463:18 + extern void e_bit121_3d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:455:18 + extern void e_bit7_0d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:456:18 + extern void e_bit7_1d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:457:18 + extern void e_bit7_2d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:458:18 + extern void e_bit7_3d(svBitVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:351:18 + extern void e_byte_0d(char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:352:18 + extern void e_byte_1d(char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:353:18 + extern void e_byte_2d(char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:354:18 + extern void e_byte_3d(char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:356:18 + extern void e_byte_unsigned_0d(unsigned char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:357:18 + extern void e_byte_unsigned_1d(unsigned char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:358:18 + extern void e_byte_unsigned_2d(unsigned char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:359:18 + extern void e_byte_unsigned_3d(unsigned char* val); + // DPI export at t/t_dpi_arg_output_unpack.v:417:18 + extern void e_chandle_0d(void** val); + // DPI export at t/t_dpi_arg_output_unpack.v:420:18 + extern void e_chandle_1d(void** val); + // DPI export at t/t_dpi_arg_output_unpack.v:424:18 + extern void e_chandle_2d(void** val); + // DPI export at t/t_dpi_arg_output_unpack.v:429:18 + extern void e_chandle_3d(void** val); + // DPI export at t/t_dpi_arg_output_unpack.v:371:18 + extern void e_int_0d(int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:372:18 + extern void e_int_1d(int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:373:18 + extern void e_int_2d(int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:374:18 + extern void e_int_3d(int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:376:18 + extern void e_int_unsigned_0d(unsigned int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:377:18 + extern void e_int_unsigned_1d(unsigned int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:378:18 + extern void e_int_unsigned_2d(unsigned int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:379:18 + extern void e_int_unsigned_3d(unsigned int* val); + // DPI export at t/t_dpi_arg_output_unpack.v:399:18 + extern void e_integer_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:400:18 + extern void e_integer_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:401:18 + extern void e_integer_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:402:18 + extern void e_integer_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:470:18 + extern void e_logic121_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:471:18 + extern void e_logic121_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:472:18 + extern void e_logic121_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:473:18 + extern void e_logic121_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:465:18 + extern void e_logic7_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:466:18 + extern void e_logic7_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:467:18 + extern void e_logic7_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:468:18 + extern void e_logic7_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:381:18 + extern void e_longint_0d(long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:382:18 + extern void e_longint_1d(long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:383:18 + extern void e_longint_2d(long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:384:18 + extern void e_longint_3d(long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:386:18 + extern void e_longint_unsigned_0d(unsigned long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:387:18 + extern void e_longint_unsigned_1d(unsigned long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:388:18 + extern void e_longint_unsigned_2d(unsigned long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:389:18 + extern void e_longint_unsigned_3d(unsigned long long* val); + // DPI export at t/t_dpi_arg_output_unpack.v:475:18 + extern void e_pack_struct_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:476:18 + extern void e_pack_struct_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:477:18 + extern void e_pack_struct_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:478:18 + extern void e_pack_struct_3d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:405:18 + extern void e_real_0d(double* val); + // DPI export at t/t_dpi_arg_output_unpack.v:406:18 + extern void e_real_1d(double* val); + // DPI export at t/t_dpi_arg_output_unpack.v:407:18 + extern void e_real_2d(double* val); + // DPI export at t/t_dpi_arg_output_unpack.v:408:18 + extern void e_real_3d(double* val); + // DPI export at t/t_dpi_arg_output_unpack.v:361:18 + extern void e_shortint_0d(short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:362:18 + extern void e_shortint_1d(short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:363:18 + extern void e_shortint_2d(short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:364:18 + extern void e_shortint_3d(short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:366:18 + extern void e_shortint_unsigned_0d(unsigned short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:367:18 + extern void e_shortint_unsigned_1d(unsigned short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:368:18 + extern void e_shortint_unsigned_2d(unsigned short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:369:18 + extern void e_shortint_unsigned_3d(unsigned short* val); + // DPI export at t/t_dpi_arg_output_unpack.v:436:18 + extern void e_string_0d(const char** val); + // DPI export at t/t_dpi_arg_output_unpack.v:439:18 + extern void e_string_1d(const char** val); + // DPI export at t/t_dpi_arg_output_unpack.v:443:18 + extern void e_string_2d(const char** val); + // DPI export at t/t_dpi_arg_output_unpack.v:448:18 + extern void e_string_3d(const char** val); + // DPI export at t/t_dpi_arg_output_unpack.v:392:18 + extern void e_time_0d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:393:18 + extern void e_time_1d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:394:18 + extern void e_time_2d(svLogicVecVal* val); + // DPI export at t/t_dpi_arg_output_unpack.v:395:18 + extern void e_time_3d(svLogicVecVal* val); + + // DPI IMPORTS + // DPI import at t/t_dpi_arg_output_unpack.v:505:41 + extern void check_exports(); + // DPI import at t/t_dpi_arg_output_unpack.v:123:36 + extern void* get_non_null(); + // DPI import at t/t_dpi_arg_output_unpack.v:206:33 + extern void i_bit121_0d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:207:33 + extern void i_bit121_1d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:208:33 + extern void i_bit121_2d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:209:33 + extern void i_bit121_3d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:201:33 + extern void i_bit7_0d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:202:33 + extern void i_bit7_1d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:203:33 + extern void i_bit7_2d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:204:33 + extern void i_bit7_3d(svBitVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:125:33 + extern void i_byte_0d(char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:126:33 + extern void i_byte_1d(char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:127:33 + extern void i_byte_2d(char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:128:33 + extern void i_byte_3d(char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:130:33 + extern void i_byte_unsigned_0d(unsigned char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:131:33 + extern void i_byte_unsigned_1d(unsigned char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:132:33 + extern void i_byte_unsigned_2d(unsigned char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:133:33 + extern void i_byte_unsigned_3d(unsigned char* val); + // DPI import at t/t_dpi_arg_output_unpack.v:191:33 + extern void i_chandle_0d(void** val); + // DPI import at t/t_dpi_arg_output_unpack.v:192:33 + extern void i_chandle_1d(void** val); + // DPI import at t/t_dpi_arg_output_unpack.v:193:33 + extern void i_chandle_2d(void** val); + // DPI import at t/t_dpi_arg_output_unpack.v:194:33 + extern void i_chandle_3d(void** val); + // DPI import at t/t_dpi_arg_output_unpack.v:145:33 + extern void i_int_0d(int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:146:33 + extern void i_int_1d(int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:147:33 + extern void i_int_2d(int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:148:33 + extern void i_int_3d(int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:150:33 + extern void i_int_unsigned_0d(unsigned int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:151:33 + extern void i_int_unsigned_1d(unsigned int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:152:33 + extern void i_int_unsigned_2d(unsigned int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:153:33 + extern void i_int_unsigned_3d(unsigned int* val); + // DPI import at t/t_dpi_arg_output_unpack.v:173:33 + extern void i_integer_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:174:33 + extern void i_integer_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:175:33 + extern void i_integer_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:176:33 + extern void i_integer_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:216:33 + extern void i_logic121_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:217:33 + extern void i_logic121_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:218:33 + extern void i_logic121_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:219:33 + extern void i_logic121_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:211:33 + extern void i_logic7_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:212:33 + extern void i_logic7_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:213:33 + extern void i_logic7_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:214:33 + extern void i_logic7_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:155:33 + extern void i_longint_0d(long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:156:33 + extern void i_longint_1d(long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:157:33 + extern void i_longint_2d(long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:158:33 + extern void i_longint_3d(long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:160:33 + extern void i_longint_unsigned_0d(unsigned long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:161:33 + extern void i_longint_unsigned_1d(unsigned long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:162:33 + extern void i_longint_unsigned_2d(unsigned long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:163:33 + extern void i_longint_unsigned_3d(unsigned long long* val); + // DPI import at t/t_dpi_arg_output_unpack.v:221:33 + extern void i_pack_struct_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:222:33 + extern void i_pack_struct_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:223:33 + extern void i_pack_struct_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:224:33 + extern void i_pack_struct_3d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:179:33 + extern void i_real_0d(double* val); + // DPI import at t/t_dpi_arg_output_unpack.v:180:33 + extern void i_real_1d(double* val); + // DPI import at t/t_dpi_arg_output_unpack.v:181:33 + extern void i_real_2d(double* val); + // DPI import at t/t_dpi_arg_output_unpack.v:182:33 + extern void i_real_3d(double* val); + // DPI import at t/t_dpi_arg_output_unpack.v:135:33 + extern void i_shortint_0d(short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:136:33 + extern void i_shortint_1d(short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:137:33 + extern void i_shortint_2d(short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:138:33 + extern void i_shortint_3d(short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:140:33 + extern void i_shortint_unsigned_0d(unsigned short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:141:33 + extern void i_shortint_unsigned_1d(unsigned short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:142:33 + extern void i_shortint_unsigned_2d(unsigned short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:143:33 + extern void i_shortint_unsigned_3d(unsigned short* val); + // DPI import at t/t_dpi_arg_output_unpack.v:196:33 + extern void i_string_0d(const char** val); + // DPI import at t/t_dpi_arg_output_unpack.v:197:33 + extern void i_string_1d(const char** val); + // DPI import at t/t_dpi_arg_output_unpack.v:198:33 + extern void i_string_2d(const char** val); + // DPI import at t/t_dpi_arg_output_unpack.v:199:33 + extern void i_string_3d(const char** val); + // DPI import at t/t_dpi_arg_output_unpack.v:166:33 + extern void i_time_0d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:167:33 + extern void i_time_1d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:168:33 + extern void i_time_2d(svLogicVecVal* val); + // DPI import at t/t_dpi_arg_output_unpack.v:169:33 + extern void i_time_3d(svLogicVecVal* val); + +#ifdef __cplusplus +} +#endif diff --git a/test_regress/t/t_dpi_unpack_bad.out b/test_regress/t/t_dpi_unpack_bad.out new file mode 100644 index 000000000..735465cf0 --- /dev/null +++ b/test_regress/t/t_dpi_unpack_bad.out @@ -0,0 +1,30 @@ +%Error-UNSUPPORTED: t/t_dpi_unpack_bad.v:21:20: Shape of the argument does not match the shape of the parameter ('logic[2:0]' v.s. 'logic[3:0]') + : ... In instance t + 21 | import_func0(sig0); + | ^~~~ +%Warning-WIDTH: t/t_dpi_unpack_bad.v:21:7: Operator TASKREF 'import_func0' expects 4 bits on the Function Argument, but Function Argument's VARREF 'sig0' generates 3 bits. + : ... In instance t + 21 | import_func0(sig0); + | ^~~~~~~~~~~~ + ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message. +%Error-UNSUPPORTED: t/t_dpi_unpack_bad.v:23:20: Shape of the argument does not match the shape of the parameter ('logic[2:0]$[0:2][0:1]' v.s. 'logic[2:0]$[0:2]') + : ... In instance t + 23 | import_func1(sig1); + | ^~~~ +%Error-UNSUPPORTED: t/t_dpi_unpack_bad.v:25:20: Shape of the argument does not match the shape of the parameter ('logic[2:0]$[0:2][0:1]' v.s. 'logic[2:0]$[0:2][0:2]') + : ... In instance t + 25 | import_func2(sig1); + | ^~~~ +%Error-UNSUPPORTED: t/t_dpi_unpack_bad.v:27:20: Shape of the argument does not match the shape of the parameter ('bit[2:0]' v.s. 'logic[2:0]') + : ... In instance t + 27 | import_func2(sig2); + | ^~~~ +%Error-UNSUPPORTED: t/t_dpi_unpack_bad.v:29:24: Argument is not an unpacked array while parameter 'in' is + : ... In instance t + 29 | import_func0(sig0[1]); + | ^ +%Warning-WIDTH: t/t_dpi_unpack_bad.v:29:7: Operator TASKREF 'import_func0' expects 4 bits on the Function Argument, but Function Argument's ARRAYSEL generates 3 bits. + : ... In instance t + 29 | import_func0(sig0[1]); + | ^~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_dpi_unpack_bad.pl b/test_regress/t/t_dpi_unpack_bad.pl new file mode 100755 index 000000000..1720150ad --- /dev/null +++ b/test_regress/t/t_dpi_unpack_bad.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, +); + +ok(1); +1; diff --git a/test_regress/t/t_dpi_unpack_bad.v b/test_regress/t/t_dpi_unpack_bad.v new file mode 100644 index 000000000..381fbe675 --- /dev/null +++ b/test_regress/t/t_dpi_unpack_bad.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2020 by Yutetsu TAKATSUKASA. This program is free software; you can +// redistribute it and/or modify it under the terms of either the GNU +// Lesser General Public License Version 3 or the Perl Artistic License +// Version 2.0. +// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +module t; + + logic [2:0] sig0[3]; + logic [2:0] sig1[3][2]; + bit [2:0] sig2[3][3]; + + import "DPI-C" function void import_func0(input logic [3:0] in [0:2]); + import "DPI-C" function void import_func1(input logic [2:0] in [0:2]); + import "DPI-C" function void import_func2(input logic [2:0] in [0:2][0:2]); + + initial begin + // packed width differs + import_func0(sig0); + // dimension differs + import_func1(sig1); + // unpacked extent differs + import_func2(sig1); + // bit v.s. logic mismatch + import_func2(sig2); + // packed var for unpacked port + import_func0(sig0[1]); + end +endmodule