diff --git a/Changes b/Changes index 580547b22..3a203916f 100644 --- a/Changes +++ b/Changes @@ -72,6 +72,7 @@ Verilator 5.025 devel * Fix SystemC BITS_PER_DIGIT in VL_ASSIGN_SBW (#5170). [Bartłomiej Chmiel, Antmicro Ltd.] * Fix non-constant replication in concats (#5171). [Arkadiusz Kozdra, Antmicro Ltd.] * Fix table optimization when applied on real data type (#5172) (#5173). [Arthur Rosa] +* Fix DPI import of null C-string (#5179). Verilator 5.024 2024-04-05 diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 6a8d64a73..c0312b826 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -219,6 +219,10 @@ static inline QData VL_CVT_Q_D(double lhs) VL_PURE { return u.q; } // clang-format on +// Return string from DPI char* +static inline std::string VL_CVT_N_CSTR(const char* lhsp) VL_PURE { + return lhsp ? std::string{lhsp} : ""s; +} // Return double from lhs (numeric) unsigned double VL_ITOR_D_W(int lbits, WDataInP const lwp) VL_PURE; diff --git a/src/V3Task.cpp b/src/V3Task.cpp index c78de7800..214ec9d3e 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -305,6 +305,9 @@ struct TaskDpiUtils final { if (portp->basicp() && portp->basicp()->keyword() == VBasicDTypeKwd::CHANDLE) { frstmt = "VL_CVT_VP_Q(" + frName; ket = ")"; + } else if (portp->basicp() && portp->basicp()->keyword() == VBasicDTypeKwd::STRING) { + frstmt = "VL_CVT_N_CSTR(" + frName; + ket = ")"; } else if ((portp->basicp() && portp->basicp()->isDpiPrimitive())) { frstmt = frName; } else { diff --git a/test_regress/t/t_dpi_import.v b/test_regress/t/t_dpi_import.v index 0274af337..bc35b3161 100644 --- a/test_regress/t/t_dpi_import.v +++ b/test_regress/t/t_dpi_import.v @@ -83,15 +83,17 @@ module t (/*AUTOARG*/ import "DPI-C" pure function void dpii_v_time (input time i, output time o); `endif - import "DPI-C" pure function int dpii_f_strlen (input string i); + import "DPI-C" pure function int dpii_f_strlen(input string i); - import "DPI-C" function void dpii_f_void (); + import "DPI-C" function string dpii_f_null(); + + import "DPI-C" function void dpii_f_void(); // Try a task - import "DPI-C" task dpii_t_void (); - import "DPI-C" context task dpii_t_void_context (); + import "DPI-C" task dpii_t_void(); + import "DPI-C" context task dpii_t_void_context(); - import "DPI-C" task dpii_t_int (input int i, output int o); + import "DPI-C" task dpii_t_int(input int i, output int o); // Try non-pure, aliasing with name import "DPI-C" dpii_fa_bit = function int oth_f_int1(input int i); @@ -229,25 +231,26 @@ module t (/*AUTOARG*/ dpii_v_time (i_tm,o_tm); if (o_tm != ~i_tm) $stop; `endif - if (dpii_f_strlen ("")!=0) $stop; - if (dpii_f_strlen ("s")!=1) $stop; - if (dpii_f_strlen ("st")!=2) $stop; - if (dpii_f_strlen ("str")!=3) $stop; - if (dpii_f_strlen ("stri")!=4) $stop; - if (dpii_f_strlen ("string_l")!=8) $stop; - if (dpii_f_strlen ("string_len")!=10) $stop; + if (dpii_f_strlen("") != 0) $stop; + if (dpii_f_strlen("s") != 1) $stop; + if (dpii_f_strlen("st") != 2) $stop; + if (dpii_f_strlen("str") != 3) $stop; + if (dpii_f_strlen("stri") != 4) $stop; + if (dpii_f_strlen("string_l") != 8) $stop; + if (dpii_f_strlen("string_len") != 10) $stop; string6 = "hello6"; `ifdef VERILATOR string6 = $c48(string6); // Don't optimize away - want to see the constant conversion function `endif - if (dpii_f_strlen (string6) != 6) $stop; + if (dpii_f_strlen(string6) != 6) $stop; + if (dpii_f_null() != "") $stop; dpii_f_void(); dpii_t_void(); dpii_t_void_context(); i_i = 32'h456789ab; - dpii_t_int (i_i,o_i); if (o_b !== ~i_b) $stop; + dpii_t_int(i_i, o_i); if (o_b !== ~i_b) $stop; // Check alias if (oth_f_int1(32'd123) !== ~32'd123) $stop; @@ -260,7 +263,7 @@ module t (/*AUTOARG*/ always @ (posedge clk) begin i_b <= ~i_b; // This once mis-threw a BLKSEQ warning - dpii_v_bit (i_b,o_b); if (o_b !== ~i_b) $stop; + dpii_v_bit(i_b, o_b); if (o_b !== ~i_b) $stop; end endmodule diff --git a/test_regress/t/t_dpi_import_c.cpp b/test_regress/t/t_dpi_import_c.cpp index 71554035e..e48b261a3 100644 --- a/test_regress/t/t_dpi_import_c.cpp +++ b/test_regress/t/t_dpi_import_c.cpp @@ -53,6 +53,7 @@ extern short int dpii_f_shortint(short int i); extern long long dpii_f_longint(long long i); extern void* dpii_f_chandle(void* i); extern const char* dpii_f_string(const char* i); +extern const char* dpii_f_null(); extern double dpii_f_real(double i); extern float dpii_f_shortreal(float i); @@ -113,6 +114,7 @@ short int dpii_f_shortint(short int i) { return ~i; } long long dpii_f_longint(long long i) { return ~i; } void* dpii_f_chandle(void* i) { return i; } const char* dpii_f_string(const char* i) { return i; } +const char* dpii_f_null() { return nullptr; } double dpii_f_real(double i) { return i + 1.5; } float dpii_f_shortreal(float i) { return i + 1.5f; }