From 2076b0219d7f07716d36613bcd2222e1b6804fde Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2019 17:19:03 -0500 Subject: [PATCH] Fix labels on functions with returns, bug1614. --- Changes | 2 ++ src/V3EmitC.cpp | 5 ++++- src/V3EmitCSyms.cpp | 7 ------- test_regress/t/t_func_redef.pl | 16 ++++++++++++++++ test_regress/t/t_func_redef.v | 27 +++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 8 deletions(-) create mode 100755 test_regress/t/t_func_redef.pl create mode 100644 test_regress/t/t_func_redef.v diff --git a/Changes b/Changes index e10653ea4..7bca6829d 100644 --- a/Changes +++ b/Changes @@ -32,6 +32,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix $display("%p") to be closer to IEEE. +**** Fix labels on functions with returns, bug1614. [Mitch Hayenga] + * Verilator 4.022 2019-11-10 diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 21e26aa77..91a695aee 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -51,6 +51,7 @@ private: bool m_suppressSemi; AstVarRef* m_wideTempRefp; // Variable that _WW macros should be setting VarVec m_ctorVarsVec; // All variables in constructor order + int m_labelNum; // Next label number int m_splitSize; // # of cfunc nodes placed into output file int m_splitFilenum; // File number being created, 0 = primary @@ -537,7 +538,8 @@ public: puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n"); } virtual void visit(AstJumpLabel* nodep) { - puts("{\n"); + nodep->labelNum(++m_labelNum); + puts("{\n"); // Make it visually obvious label jumps outside these iterateAndNextNull(nodep->stmtsp()); puts("}\n"); puts("__Vlabel"+cvtToStr(nodep->labelNum())+": ;\n"); @@ -914,6 +916,7 @@ public: void init() { m_suppressSemi = false; m_wideTempRefp = NULL; + m_labelNum = 0; m_splitSize = 0; m_splitFilenum = 0; } diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 7e80172af..dfbc62b73 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -93,7 +93,6 @@ class EmitCSyms : EmitCBaseVisitor { ScopeNameHierarchy m_vpiScopeHierarchy; // The actual hierarchy of scopes V3LanguageWords m_words; // Reserved word detector int m_coverBins; // Coverage bin number - int m_labelNum; // Next label number bool m_dpiHdrOnly; // Only emit the DPI header int m_numStmts; // Number of statements output int m_funcNum; // CFunc split function number @@ -272,7 +271,6 @@ class EmitCSyms : EmitCBaseVisitor { virtual void visit(AstNodeModule* nodep) { nameCheck(nodep); m_modp = nodep; - m_labelNum = 0; iterateChildren(nodep); m_modp = NULL; } @@ -331,10 +329,6 @@ class EmitCSyms : EmitCBaseVisitor { nodep->binNum(m_coverBins++); } } - virtual void visit(AstJumpLabel* nodep) { - nodep->labelNum(++m_labelNum); - iterateChildren(nodep); - } virtual void visit(AstCFunc* nodep) { nameCheck(nodep); if (nodep->dpiImport() || nodep->dpiExportWrapper()) { @@ -359,7 +353,6 @@ public: m_funcp = NULL; m_modp = NULL; m_coverBins = 0; - m_labelNum = 0; m_numStmts = 0; m_funcNum = 0; m_ofpBase = NULL; diff --git a/test_regress/t/t_func_redef.pl b/test_regress/t/t_func_redef.pl new file mode 100755 index 000000000..5c448de7c --- /dev/null +++ b/test_regress/t/t_func_redef.pl @@ -0,0 +1,16 @@ +#!/usr/bin/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. + +scenarios(simulator => 1); + +compile( + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_redef.v b/test_regress/t/t_func_redef.v new file mode 100644 index 000000000..042dfec12 --- /dev/null +++ b/test_regress/t/t_func_redef.v @@ -0,0 +1,27 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +function automatic integer min(input integer a, input integer b); + return (a < b) ? a : b; +endfunction + +module t + #(parameter A=16, parameter B=8) + (/*AUTOARG*/ + // Outputs + c, + // Inputs + a, b + ); + + input [A-1:0] a; + input [B-1:0] b; + output logic [min(A,B)-1:0] c; + + always_comb + for (int i = 0; i < min(A,B); i++) + assign c[i] = a[i] | b[i]; + +endmodule