From 5bf92c9d3adf2b81f00bdcb5fea0680cb696b19f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 2 Jan 2013 18:35:21 -0500 Subject: [PATCH] Fix task inlining under case values, bug598. Note this reorders high level operations, so may change loose some optimizations. --- Changes | 2 +- src/Verilator.cpp | 9 ++++--- test_regress/t/t_func_under2.pl | 18 +++++++++++++ test_regress/t/t_func_under2.v | 45 +++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) create mode 100755 test_regress/t/t_func_under2.pl create mode 100644 test_regress/t/t_func_under2.v diff --git a/Changes b/Changes index 5c98644a4..cf566bae5 100644 --- a/Changes +++ b/Changes @@ -11,7 +11,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix non-integer vpi_get_value, bug587. [Rich Porter] -**** Fix task inlining under $display, bug589. [Holger Waechtler] +**** Fix task inlining under $display and case, bug589, bug598. [Holger Waechtler] **** Fix package import of non-localparam parameter, bug591. [Jeremy Bennett] diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 06b40638d..b84e090de 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -314,6 +314,11 @@ void process () { v3Global.checkTree(); V3Global::dumpGlobalTree("const.tree"); + // Convert case statements to if() blocks. Must be after V3Unknown + // Must be before V3Task so don't need to deal with task in case value compares + V3Case::caseAll(v3Global.rootp()); + V3Global::dumpGlobalTree("case.tree"); + // Inline all tasks V3Task::taskAll(v3Global.rootp()); V3Global::dumpGlobalTree("task.tree"); @@ -331,10 +336,6 @@ void process () { V3Slice::sliceAll(v3Global.rootp()); V3Global::dumpGlobalTree("slices.tree"); - // Convert case statements to if() blocks. Must be after V3Unknown - V3Case::caseAll(v3Global.rootp()); - V3Global::dumpGlobalTree("case.tree"); - // Push constants across variables and remove redundant assignments V3Const::constifyAll(v3Global.rootp()); V3Global::dumpGlobalTree("const.tree"); diff --git a/test_regress/t/t_func_under2.pl b/test_regress/t/t_func_under2.pl new file mode 100755 index 000000000..f91289753 --- /dev/null +++ b/test_regress/t/t_func_under2.pl @@ -0,0 +1,18 @@ +#!/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. + +compile ( + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_func_under2.v b/test_regress/t/t_func_under2.v new file mode 100644 index 000000000..ad54fe428 --- /dev/null +++ b/test_regress/t/t_func_under2.v @@ -0,0 +1,45 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Wilson Snyder. + +// bug598 + +module t (/*AUTOARG*/ + // Outputs + val, + // Inputs + clk + ); + + input clk; + output integer val; + integer dbg_addr = 0; + + function func1; + input en; + input [31:0] a; + func1 = en && (a == 1); + endfunction + + function func2; + input en; + input [31:0] a; + func2 = en && (a == 2); + endfunction + + always @(posedge clk) begin + case( 1'b1 ) + // This line is OK: + func1(1'b1, dbg_addr) : val = 1; + // This fails: + // %Error: Internal Error: test.v:23: ../V3Task.cpp:993: Function not underneath a statement + // %Error: Internal Error: See the manual and http://www.veripool.org/verilator for more assistance. + func2(1'b1, dbg_addr) : val = 2; + default : val = 0; + endcase + // + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule