From 08330bad0b902e291ddfd73b866b7d2b207bf4a4 Mon Sep 17 00:00:00 2001 From: Peter Monsson Date: Fri, 21 Apr 2023 14:07:22 +0200 Subject: [PATCH] Fix variables in class methods to be automatic (#4111) (#4137) --- src/V3LinkParse.cpp | 3 ++ test_regress/t/t_class_param_type.v | 4 +- test_regress/t/t_static_function_in_class.pl | 21 ++++++++ test_regress/t/t_static_function_in_class.v | 51 ++++++++++++++++++++ 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_static_function_in_class.pl create mode 100644 test_regress/t/t_static_function_in_class.v diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 621dd013d..3b7d8eb0a 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -231,6 +231,9 @@ private: nodep->v3warn(STATICVAR, "Static variable with assignment declaration declared in a " "loop converted to automatic"); } + if (m_ftaskp && m_ftaskp->classMethod() && nodep->lifetime().isNone()) { + nodep->lifetime(VLifetime::AUTOMATIC); + } if (nodep->lifetime().isNone() && nodep->varType() != VVarType::PORT) { nodep->lifetime(m_lifetime); } diff --git a/test_regress/t/t_class_param_type.v b/test_regress/t/t_class_param_type.v index 86b1d8f67..e9f17ef14 100644 --- a/test_regress/t/t_class_param_type.v +++ b/test_regress/t/t_class_param_type.v @@ -29,7 +29,7 @@ typedef cls_t cls2_t; class Singleton #(type T=int); static function Singleton#(T) self; - Singleton#(T) c = new; + static Singleton#(T) c = new; return c; endfunction function int get_size; @@ -39,7 +39,7 @@ endclass class SingletonUnusedDefault #(type T=int); static function SingletonUnusedDefault#(T) self; - SingletonUnusedDefault#(T) c = new; + static SingletonUnusedDefault#(T) c = new; return c; endfunction endclass diff --git a/test_regress/t/t_static_function_in_class.pl b/test_regress/t/t_static_function_in_class.pl new file mode 100755 index 000000000..b46d46042 --- /dev/null +++ b/test_regress/t/t_static_function_in_class.pl @@ -0,0 +1,21 @@ +#!/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(simulator => 1); + +compile( + ); + +execute( + check_finished => 1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_static_function_in_class.v b/test_regress/t/t_static_function_in_class.v new file mode 100644 index 000000000..ab9a80288 --- /dev/null +++ b/test_regress/t/t_static_function_in_class.v @@ -0,0 +1,51 @@ +// DESCRIPTION: Verilator: Simple static elaboration case +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2015 by Todd Strader. +// SPDX-License-Identifier: CC0-1.0 + +class string_utils; + typedef string array_of_string[]; + + static function array_of_string split_by_dash(string s); + string parts[$]; + int last_char_position = -1; + for (int i = 0; i < s.len(); i++) begin + if (i == s.len()-1) begin + parts.push_back(s.substr(last_char_position+1, i)); + end + // Can't remove this, because then the code will work + if (string'(s[i]) == "-") begin + parts.push_back(s.substr(last_char_position+1, i-1)); + last_char_position = i; + end + end // for (int i = 0; i < s.len(); i++) + return parts; + endfunction // split_by_dash +endclass // string_utils + +class filter; + local static filter single_instance; + + static function filter get(); + if (single_instance == null) + single_instance = new(); + return single_instance; + endfunction // get + + local function new(); + string parts[] = string_utils::split_by_dash("*"); + if (parts.size() != 1) + $fatal(0, "Expected single element"); + if (parts[0] != "*") + $fatal(0, "Expected element to be *"); + endfunction // new +endclass // filter + +module t (/*AUTOARG*/); + const filter _filter = filter::get(); + initial begin + $write("*-* All Finished *-*\n"); + $finish(); + end +endmodule