diff --git a/Changes b/Changes index 9e5352266..855243585 100644 --- a/Changes +++ b/Changes @@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Support x in $readmem, bug1180. [Arthur Kahlich] +**** Support packed struct DPI imports, bug1190. [Rob Stoddard] + **** Fix GCC 6 warnings. **** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson] diff --git a/src/V3Ast.h b/src/V3Ast.h index 4ee7a174e..2f8a75bab 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -396,7 +396,7 @@ public: return (m_e==LOGIC || m_e==BIT); } bool isDpiUnsupported() const { - return (m_e==LOGIC || m_e==TIME); + return (m_e==TIME); } bool isDpiUnsignable() const { // Can add "unsigned" to DPI return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER); diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 937e70d74..55e978a60 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -158,7 +158,7 @@ private: if (oldactivep->sensesp() != m_activep->sensesp()) { if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN) && !varrefp->varp()->user2()) { - varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<varp()->prettyName()<varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "<varp()->prettyName()<warnMore()<<"... Location of first driving block"<warnMore()<<"... Location of other driving block"); varrefp->varp()->user2(true); diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 2edf928b0..601ea1c99 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -938,6 +938,8 @@ private: if (!portp->basicp() || portp->basicp()->keyword().isDpiUnsupported()) { portp->v3error("Unsupported: DPI argument of type "<basicp()->prettyTypeName()<warnMore()<<"... For best portability, use bit, byte, int, or longint"); + // We don't warn on logic either, although the 4-stateness is lost. + // That's what other simulators do. } } } else { diff --git a/test_regress/t/t_dpi_import.v b/test_regress/t/t_dpi_import.v index bb4cd6181..48ce47db3 100644 --- a/test_regress/t/t_dpi_import.v +++ b/test_regress/t/t_dpi_import.v @@ -21,6 +21,8 @@ module t (/*AUTOARG*/ ); input clk; + typedef struct packed { bit [47:0] lo; bit [47:0] hi; } str_t; + // Allowed import return types: // void, byte, shortint, int, longint, real, shortreal, chandle, and string // Scalar bit and logic @@ -53,6 +55,7 @@ module t (/*AUTOARG*/ import "DPI-C" pure function void dpii_v_byte (input byte i, output byte o); import "DPI-C" pure function void dpii_v_shortint (input shortint i, output shortint o); import "DPI-C" pure function void dpii_v_longint (input longint i, output longint o); + import "DPI-C" pure function void dpii_v_struct (input str_t i, output str_t o); import "DPI-C" pure function void dpii_v_chandle (input chandle i, output chandle o); import "DPI-C" pure function void dpii_v_string (input string i, output string o); import "DPI-C" pure function void dpii_v_real (input real i, output real o); @@ -96,6 +99,7 @@ module t (/*AUTOARG*/ byte i_y, o_y; shortint i_s, o_s; longint i_l, o_l; + str_t i_t, o_t; int unsigned i_iu, o_iu; shortint unsigned i_su, o_su; longint unsigned i_lu, o_lu; @@ -133,6 +137,7 @@ module t (/*AUTOARG*/ i_su= {1'b1,wide[16-2:0]}; i_l = {1'b1,wide[64-2:0]}; i_lu= {1'b1,wide[64-2:0]}; + i_t = {1'b1,wide[95-1:0]}; i_d = 32.1; `ifndef NO_SHORTREAL i_f = 30.2; @@ -173,6 +178,7 @@ module t (/*AUTOARG*/ dpii_v_uint (i_iu,o_iu); if (o_iu !== ~i_iu) $stop; dpii_v_ushort (i_su,o_su); if (o_su !== ~i_su) $stop; dpii_v_ulong (i_lu,o_lu); if (o_lu !== ~i_lu) $stop; + dpii_v_struct (i_t,o_t); if (o_t !== ~i_t) $stop; dpii_v_chandle (i_c,o_c); if (o_c !== i_c) $stop; dpii_v_string (i_n,o_n); if (o_n != i_n) $stop; dpii_v_real (i_d,o_d); if (o_d != i_d+1.5) $stop; diff --git a/test_regress/t/t_dpi_import_c.cpp b/test_regress/t/t_dpi_import_c.cpp index 02dcfb91f..e3fab93c7 100644 --- a/test_regress/t/t_dpi_import_c.cpp +++ b/test_regress/t/t_dpi_import_c.cpp @@ -58,6 +58,7 @@ extern "C" { extern void dpii_v_ushort (unsigned short i, unsigned short *o); extern void dpii_v_longint (long long i, long long *o); extern void dpii_v_ulong (unsigned long long i, unsigned long long *o); + extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o); extern void dpii_v_chandle (void* i, void* *o); extern void dpii_v_string (const char* i, const char** o); extern void dpii_v_real (double i, double* o); @@ -107,6 +108,13 @@ void dpii_v_string (const char* i, const char** o) { *o = i; } void dpii_v_real (double i, double* o) { *o = i + 1.5; } void dpii_v_shortreal(float i, float* o) { *o = i + 1.5; } +void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o) { + o[0] = ~i[0]; + o[1] = ~i[1]; + o[2] = ~i[2]; + o[3] = ~i[3]; + o[4] = ~i[4]; +} void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) { o[0] = ~i[0]; o[1] = ~i[1]; diff --git a/test_regress/t/t_dpi_logic_bad.v b/test_regress/t/t_dpi_logic_bad.v index 9ff259396..fb4cfa8af 100644 --- a/test_regress/t/t_dpi_logic_bad.v +++ b/test_regress/t/t_dpi_logic_bad.v @@ -7,8 +7,8 @@ module t (); - // Can't handle logic (yet?) - import "DPI-C" dpii_fa_bit = function int oth_f_int1(input logic [2:0] i); + // Can't handle time (yet?) + import "DPI-C" dpii_fa_bit = function int oth_f_int1(input time i); initial begin $stop; diff --git a/test_regress/t/t_lint_multidriven_bad.pl b/test_regress/t/t_lint_multidriven_bad.pl index 8eb339845..d4855bcb7 100755 --- a/test_regress/t/t_lint_multidriven_bad.pl +++ b/test_regress/t/t_lint_multidriven_bad.pl @@ -16,11 +16,11 @@ compile ( make_top_shell => 0, make_main => 0, expect=> -'%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: t.mem +'%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks with different clocking: t.mem %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block %Warning-MULTIDRIVEN: Use ".*" and lint_on around source to disable this message. -%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks: out2 +%Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: Signal has multiple driving blocks with different clocking: out2 %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of first driving block %Warning-MULTIDRIVEN: t/t_lint_multidriven_bad.v:\d+: ... Location of other driving block %Error: Exiting due to.*',