From c3dd6f5344d69d03be60c3ddd0800bdfe05ade53 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 5 Mar 2022 16:19:53 -0500 Subject: [PATCH] Fix public function arguments that are arrayed (#3316). --- Changes | 1 + src/V3AstNodes.cpp | 42 ++++++++++++++++++++-------------- test_regress/t/t_func_public.v | 7 ++++++ 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/Changes b/Changes index d6c2cdff4..07c6c9b30 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,7 @@ Verilator 4.219 devel * Add trace dumpvars() call for selective runtime tracing (#3322). [Shunyao CAD] * Fix skipping public enum values with four-state values (#3303). * Fix $readmem file not found to be warning not error (#3310). [Alexander Grobman] +* Fix public function arguments that are arrayed (#3316). [pawel256] * Fix compile error with --trace-fst --sc (#3332). [leavinel] * Fix crash in recursive module inlining (#3324). [Larry Doolittle] diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 0ec29945f..4b90ed159 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -454,25 +454,33 @@ string AstVar::cPubArgType(bool named, bool forReturn) const { if (forReturn) named = false; string arg; if (isWide() && isReadOnly()) arg += "const "; - if (widthMin() == 1) { - arg += "bool"; - } else if (widthMin() <= VL_IDATASIZE) { - arg += "uint32_t"; - } else if (widthMin() <= VL_QUADSIZE) { - arg += "vluint64_t"; - } else { - arg += "uint32_t"; // []'s added later - } - if (isWide()) { - if (forReturn) { - v3warn(E_UNSUPPORTED, "Unsupported: Public functions with >64 bit outputs; " - "make an output of a public task instead"); + const bool isRef = !forReturn && (isWritable() || direction().isRefOrConstRef()); + if (VN_IS(dtypeSkipRefp(), BasicDType) && !dtypeSkipRefp()->isDouble() + && !dtypeSkipRefp()->isString()) { + // Backward compatible type declaration + if (widthMin() == 1) { + arg += "bool"; + } else if (widthMin() <= VL_IDATASIZE) { + arg += "uint32_t"; + } else if (widthMin() <= VL_QUADSIZE) { + arg += "vluint64_t"; + } else { + arg += "uint32_t"; // []'s added later + } + if (isWide()) { + if (forReturn) { + v3warn(E_UNSUPPORTED, "Unsupported: Public functions with >64 bit outputs; " + "make an output of a public task instead"); + } + arg += " (& " + name(); + arg += ")[" + cvtToStr(widthWords()) + "]"; + } else { + if (isRef) arg += "&"; + if (named) arg += " " + name(); } - arg += " (& " + name(); - arg += ")[" + cvtToStr(widthWords()) + "]"; } else { - if (!forReturn && (isWritable() || direction().isRefOrConstRef())) arg += "&"; - if (named) arg += " " + name(); + // Newer internal-compatible types + arg += dtypep()->cType((named ? name() : string{}), true, isRef); } return arg; } diff --git a/test_regress/t/t_func_public.v b/test_regress/t/t_func_public.v index d97a93b34..00a58e67e 100644 --- a/test_regress/t/t_func_public.v +++ b/test_regress/t/t_func_public.v @@ -32,6 +32,13 @@ module t (clk); $write("Hello in publicTop\n"); endtask + task test_task(input [19:0] in [2], output [19:0] out [2]); + // Issue 3316 + // verilator public + out[0] = in[1]; + out[1] = in[0]; + endtask + endmodule module tpub (