From 68e0cf5523e5542ef00564c12c961bdf270cca06 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 27 Oct 2024 10:08:18 -0400 Subject: [PATCH 001/171] devel release --- CMakeLists.txt | 2 +- Changes | 5 +++++ configure.ac | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 59ae991b5..7d1528033 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime project( Verilator - VERSION 5.030 + VERSION 5.031 HOMEPAGE_URL https://verilator.org LANGUAGES CXX ) diff --git a/Changes b/Changes index ad9894665..4ded496a4 100644 --- a/Changes +++ b/Changes @@ -8,6 +8,11 @@ The changes in each Verilator version are described below. The contributors that suggested a given feature are shown in []. Thanks! +Verilator 5.031 devel +========================== + + + Verilator 5.030 2024-10-27 ========================== diff --git a/configure.ac b/configure.ac index 6d01254b4..1f0897f7f 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ # Then 'make maintainer-dist' #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) -AC_INIT([Verilator],[5.030 2024-10-27], +AC_INIT([Verilator],[5.031 devel], [https://verilator.org], [verilator],[https://verilator.org]) From 0f2a8c6c22ed8c6e28e101e44375d7f834b25c58 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Tue, 29 Oct 2024 07:27:40 -0400 Subject: [PATCH 002/171] Fix BLKANDNBLK for for VARXREFs (#5569) --- src/V3Unknown.cpp | 2 +- test_regress/t/t_array_non_blocking_loop.py | 18 ++++++++++ test_regress/t/t_array_non_blocking_loop.v | 38 +++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_array_non_blocking_loop.py create mode 100644 test_regress/t/t_array_non_blocking_loop.v diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 13107c8a4..96d427b22 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -127,7 +127,7 @@ class UnknownVisitor final : public VNVisitor { AstNodeExpr* const selExprp = prep->cloneTree(true); AstNodeExpr* currentExprp = selExprp; while (AstNodeExpr* itrSelExprp = VN_AS(currentExprp->op1p(), NodeExpr)) { - if (AstVarRef* const selRefp = VN_CAST(itrSelExprp, VarRef)) { + if (AstNodeVarRef* const selRefp = VN_CAST(itrSelExprp, NodeVarRef)) { // Mark the variable reference as READ access to avoid assignment issues selRefp->access(VAccess::READ); break; diff --git a/test_regress/t/t_array_non_blocking_loop.py b/test_regress/t/t_array_non_blocking_loop.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_array_non_blocking_loop.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_array_non_blocking_loop.v b/test_regress/t/t_array_non_blocking_loop.v new file mode 100644 index 000000000..aada1da78 --- /dev/null +++ b/test_regress/t/t_array_non_blocking_loop.v @@ -0,0 +1,38 @@ +// DESCRIPTION: Verilator: Demonstrate struct literal param assignment problem +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + + +interface intf + #( + parameter int write_data_width) (); + logic [write_data_width-1:0] writedata; +endinterface +module t( /*AUTOARG*/ + clk +); + + input clk; + generate + genvar num_chunks; + for (num_chunks = 1; num_chunks <= 2; num_chunks++) begin : gen_n + localparam int decoded_width = 55 * num_chunks; + intf #( + .write_data_width(decoded_width)) + the_intf (); + always @(posedge clk) begin + for (int i = 0; i < decoded_width; i++) + the_intf.writedata[i] <= '1; + $display("%0d", the_intf.writedata); + end + end + endgenerate + + // finish report + always @ (posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 9fae951d9d1c366e26f5d4f4a73369807daff0a8 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 31 Oct 2024 14:38:53 -0400 Subject: [PATCH 003/171] Fix --output-groups leftover files issue (#5574) --- src/V3EmitMk.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 48c6ad247..3a6032921 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -346,12 +346,14 @@ private: } } - if (bucket.m_concatenatedFilenames.size() == 1) { + const bool lastBucketAndLeftovers + = (i + 1 == list.m_bucketsNum) && (fileIt != list.m_files.end()); + if (bucket.m_concatenatedFilenames.size() > 1 || lastBucketAndLeftovers) { + m_outputFiles.push_back(std::move(bucket)); + } else if (bucket.m_concatenatedFilenames.size() == 1) { // Unwrap the bucket if it contains only one file. m_outputFiles.push_back( {std::move(bucket.m_concatenatedFilenames.front()), {}}); - } else if (bucket.m_concatenatedFilenames.size() > 1) { - m_outputFiles.push_back(std::move(bucket)); } // Most likely no bucket will be empty in normal situations. If it happen the // bucket will just be dropped. @@ -359,6 +361,8 @@ private: for (; fileIt != list.m_files.end(); ++fileIt) { // The Work List is out of buckets, but some files were left. // Add them to the last bucket. + UASSERT(m_outputFiles.back().isConcatenatingFile(), + "Cannot add leftover files to a single file"); m_outputFiles.back().m_concatenatedFilenames.push_back(fileIt->m_filename); } } From dab826bef9ff93a760cddf9d7b3c162bd4b6f507 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 31 Oct 2024 17:02:37 -0400 Subject: [PATCH 004/171] VPI error instead of fatal for vpi_get_value() on large signals (#5571) --- include/verilated_vpi.cpp | 8 +++++--- test_regress/driver.py | 3 ++- test_regress/t/t_vpi_var.cpp | 28 ++++++++++++++++++++++++++++ test_regress/t/t_vpi_var.v | 2 ++ test_regress/t/t_vpi_var2.v | 2 ++ test_regress/t/t_vpi_var3.v | 2 ++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index ed2009ecf..c066ae8a7 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -2415,9 +2415,11 @@ void vl_get_value(const VerilatedVar* varp, void* varDatap, p_vpi_value valuep, } else if (varp->vltype() == VLVT_WDATA) { const int words = VL_WORDS_I(varp->packed().elements()); if (VL_UNCOVERABLE(words >= VL_VALUE_STRING_MAX_WORDS)) { - VL_FATAL_MT(__FILE__, __LINE__, "", - "vpi_get_value with more than VL_VALUE_STRING_MAX_WORDS; increase and " - "recompile"); + VL_VPI_ERROR_( + __FILE__, __LINE__, + "vpi_get_value with more than VL_VALUE_STRING_MAX_WORDS; increase and " + "recompile"); + return; } const WDataInP datap = (reinterpret_cast(varDatap)); for (int i = 0; i < words; ++i) { diff --git a/test_regress/driver.py b/test_regress/driver.py index 71d3ed4d0..8f8149948 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -683,7 +683,8 @@ class VlTest: self.all_run_flags = [] self.pli_flags = [ - "-I" + os.environ['VERILATOR_ROOT'] + "/include/vltstd", "-fPIC", "-shared" + "-I" + os.environ['VERILATOR_ROOT'] + "/include/vltstd", + "-I" + os.environ['VERILATOR_ROOT'] + "/include", "-fPIC", "-shared" ] if platform.system() == 'Darwin': self.pli_flags += ["-Wl,-undefined,dynamic_lookup"] diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 8f4189271..7ed632ecc 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -34,6 +34,10 @@ #endif +#ifdef VERILATOR +#include "verilated.h" +#endif + #include #include #include @@ -253,6 +257,29 @@ int _mon_check_value_callbacks() { return 0; } +int _mon_check_too_big() { +#ifdef VERILATOR + s_vpi_value v; + v.format = vpiVectorVal; + + TestVpiHandle h = VPI_HANDLE("too_big"); + CHECK_RESULT_NZ(h); + + Verilated::fatalOnVpiError(false); + vpi_get_value(h, &v); + Verilated::fatalOnVpiError(true); + s_vpi_error_info info; + CHECK_RESULT_NZ(vpi_chk_error(&info)); + + v.format = vpiStringVal; + vpi_get_value(h, &v); + CHECK_RESULT_Z(vpi_chk_error(nullptr)); + CHECK_RESULT_CSTR_STRIP(v.value.str, "some text"); +#endif + + return 0; +} + int _mon_check_var() { TestVpiHandle vh1 = VPI_HANDLE("onebit"); CHECK_RESULT_NZ(vh1); @@ -935,6 +962,7 @@ extern "C" int mon_check() { if (int status = _mon_check_putget_str(NULL)) return status; if (int status = _mon_check_vlog_info()) return status; if (int status = _mon_check_delayed()) return status; + if (int status = _mon_check_too_big()) return status; #ifndef IS_VPI VerilatedVpi::selfTest(); #endif diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 8828b1776..52d92dfc4 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -49,6 +49,7 @@ extern "C" int mon_check(); reg [31:0] text_word /*verilator public_flat_rw @(posedge clk) */; reg [63:0] text_long /*verilator public_flat_rw @(posedge clk) */; reg [511:0] text /*verilator public_flat_rw @(posedge clk) */; + reg [2047:0] too_big /*verilator public_flat_rw @(posedge clk) */; integer status; @@ -68,6 +69,7 @@ extern "C" int mon_check(); text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; + too_big = "some text"; real1 = 1.0; str1 = "hello"; diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 85b015766..691502419 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -67,6 +67,7 @@ extern "C" int mon_check(); reg [31:0] text_word; reg [63:0] text_long; reg [511:0] text; + reg [2047:0] too_big; /*verilator public_off*/ integer status; @@ -88,6 +89,7 @@ extern "C" int mon_check(); text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; + too_big = "some text"; real1 = 1.0; str1 = "hello"; diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index 6e62d5c66..e81fb48db 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -49,6 +49,7 @@ extern "C" int mon_check(); reg [31:0] text_word; reg [63:0] text_long; reg [511:0] text; + reg [2047:0] too_big; integer status; @@ -68,6 +69,7 @@ extern "C" int mon_check(); text_word = "Word"; text_long = "Long64b"; text = "Verilog Test module"; + too_big = "some text"; real1 = 1.0; str1 = "hello"; From 4448778dbf0af03103ee51d99f81d2ddffc06f3a Mon Sep 17 00:00:00 2001 From: Andrew Nolte Date: Fri, 1 Nov 2024 09:30:44 -0400 Subject: [PATCH 005/171] Add coverage point hierarchy to coverage reports (#5575) (#5576) --- src/VlcPoint.h | 3 +- test_regress/t/t_cover_line.out | 244 +++++++++++------------ test_regress/t/t_cover_toggle_points.out | 116 +++++------ 3 files changed, 182 insertions(+), 181 deletions(-) diff --git a/src/VlcPoint.h b/src/VlcPoint.h index aeb326fca..d087fb528 100644 --- a/src/VlcPoint.h +++ b/src/VlcPoint.h @@ -63,6 +63,7 @@ public: // KEY ACCESSORS string filename() const { return keyExtract(VL_CIK_FILENAME); } string comment() const { return keyExtract(VL_CIK_COMMENT); } + string hier() const { return keyExtract(VL_CIK_HIER); } string type() const { return keyExtract(VL_CIK_TYPE); } string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe "" string linescov() const { return keyExtract(VL_CIK_LINESCOV); } @@ -98,7 +99,7 @@ public: void dumpAnnotate(std::ostream& os, unsigned annotateMin) const { os << (ok(annotateMin) ? "+" : "-"); os << std::setw(6) << std::setfill('0') << count(); - os << " point: comment=" << comment(); + os << " point: comment=" << comment() << " hier=" << hier(); os << "\n"; } }; diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out index 4ca952e78..ec76b5936 100644 --- a/test_regress/t/t_cover_line.out +++ b/test_regress/t/t_cover_line.out @@ -14,11 +14,11 @@ reg toggle; %000001 initial toggle=0; --000001 point: comment=block +-000001 point: comment=block hier=top.t integer cyc; %000001 initial cyc=1; --000001 point: comment=block +-000001 point: comment=block hier=top.t wire [7:0] cyc_copy = cyc[7:0]; @@ -52,136 +52,136 @@ par par1 (/*AUTOINST*/); 000010 always @ (posedge clk) begin -+000010 point: comment=block ++000010 point: comment=block hier=top.t ~000010 if (cyc!=0) begin -+000010 point: comment=if --000000 point: comment=else ++000010 point: comment=if hier=top.t +-000000 point: comment=else hier=top.t 000010 cyc <= cyc + 1; -+000010 point: comment=if ++000010 point: comment=if hier=top.t 000010 toggle <= '0; -+000010 point: comment=if ++000010 point: comment=if hier=top.t // Single and multiline if %000009 if (cyc==3) $write(""); --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t %000009 if (cyc==3) --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t %000001 begin --000001 point: comment=if +-000001 point: comment=if hier=top.t %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.t end // Single and multiline else %000009 if (cyc==3) ; else $write(""); --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t %000009 if (cyc==3) ; --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t else %000009 begin --000009 point: comment=else +-000009 point: comment=else hier=top.t %000009 $write(""); --000009 point: comment=else +-000009 point: comment=else hier=top.t end // Single and multiline if else %000009 if (cyc==3) $write(""); else $write(""); --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t %000009 if (cyc==3) --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t +-000009 point: comment=else hier=top.t %000001 begin --000001 point: comment=if +-000001 point: comment=if hier=top.t %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.t end else %000009 begin --000009 point: comment=else +-000009 point: comment=else hier=top.t %000009 $write(""); --000009 point: comment=else +-000009 point: comment=else hier=top.t end // multiline elseif %000001 if (cyc==3) --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t %000001 begin --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t %000001 $write(""); --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t end %000001 else if (cyc==4) --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t %000001 begin --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t %000001 $write(""); --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t end %000007 else if (cyc==5) --000001 point: comment=if --000007 point: comment=else +-000001 point: comment=if hier=top.t +-000007 point: comment=else hier=top.t %000001 begin --000001 point: comment=if +-000001 point: comment=if hier=top.t %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.t end else %000007 begin --000007 point: comment=else +-000007 point: comment=else hier=top.t %000007 $write(""); --000007 point: comment=else +-000007 point: comment=else hier=top.t end // Single and multiline while %000000 while (0); --000000 point: comment=block +-000000 point: comment=block hier=top.t %000000 while (0) begin --000000 point: comment=block +-000000 point: comment=block hier=top.t %000000 $write(""); --000000 point: comment=block +-000000 point: comment=block hier=top.t end %000000 do ; while (0); --000000 point: comment=block +-000000 point: comment=block hier=top.t ~000010 do begin --000000 point: comment=block -+000010 point: comment=if +-000000 point: comment=block hier=top.t ++000010 point: comment=if hier=top.t ~000010 $write(""); --000000 point: comment=block -+000010 point: comment=if +-000000 point: comment=block hier=top.t ++000010 point: comment=if hier=top.t %000000 end while (0); --000000 point: comment=block +-000000 point: comment=block hier=top.t //=== // Task and complicated %000001 if (cyc==3) begin --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t %000001 toggle <= '1; --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t end %000001 else if (cyc==5) begin --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t `ifdef VERILATOR %000001 $c("this->call_task();"); --000001 point: comment=elsif +-000001 point: comment=elsif hier=top.t `else call_task(); `endif end %000007 else if (cyc==10) begin --000001 point: comment=if --000007 point: comment=else +-000001 point: comment=if hier=top.t +-000007 point: comment=else hier=top.t %000001 $write("*-* All Finished *-*\n"); --000001 point: comment=if +-000001 point: comment=if hier=top.t %000001 $finish; --000001 point: comment=if +-000001 point: comment=if hier=top.t end end end %000001 task call_task; --000001 point: comment=block +-000001 point: comment=block hier=top.t /* verilator public */ %000001 t1.center_task(1'b1); --000001 point: comment=block +-000001 point: comment=block hier=top.t endtask endmodule @@ -193,16 +193,16 @@ input clk; input toggle; 000020 always @ (posedge clk) begin -+000020 point: comment=block ++000020 point: comment=block hier=top.t.a* ~000018 if (toggle) begin // CHECK_COVER(0,"top.t.a*",18) --000002 point: comment=if -+000018 point: comment=else +-000002 point: comment=if hier=top.t.a* ++000018 point: comment=else hier=top.t.a* %000002 $write(""); --000002 point: comment=if +-000002 point: comment=if hier=top.t.a* // t.a1 and t.a2 collapse to a count of 2 end 000018 if (toggle) begin // *** t_cover_line.vlt turns this off -+000018 point: comment=else ++000018 point: comment=else hier=top.t.a* $write(""); // CHECK_COVER_MISSING(0) // This doesn't even get added `ifdef ATTRIBUTE @@ -222,25 +222,25 @@ /* verilator public_module */ 000020 always @ (posedge clk) begin -+000020 point: comment=block ++000020 point: comment=block hier=top.t.b* 000020 $write(""); // Always covered -+000020 point: comment=block ++000020 point: comment=block hier=top.t.b* ~000020 if (0) begin // CHECK_COVER(0,"top.t.b*",0) --000000 point: comment=if -+000020 point: comment=else +-000000 point: comment=if hier=top.t.b* ++000020 point: comment=else hier=top.t.b* // Make sure that we don't optimize away zero buckets %000000 $write(""); --000000 point: comment=if +-000000 point: comment=if hier=top.t.b* end ~000018 if (toggle) begin // CHECK_COVER(0,"top.t.b*",2) --000002 point: comment=if -+000018 point: comment=else +-000002 point: comment=if hier=top.t.b* ++000018 point: comment=else hier=top.t.b* // t.b1 and t.b2 collapse to a count of 2 %000002 $write(""); --000002 point: comment=if +-000002 point: comment=if hier=top.t.b* end 000018 if (toggle) begin : block -+000018 point: comment=else ++000018 point: comment=else hier=top.t.b* // This doesn't `ifdef ATTRIBUTE // verilator coverage_block_off @@ -255,32 +255,32 @@ class Cls; bit m_toggle; %000001 function new(bit toggle); --000001 point: comment=block +-000001 point: comment=block hier=top.$unit::Cls__Vclpkg %000001 m_toggle = toggle; --000001 point: comment=block +-000001 point: comment=block hier=top.$unit::Cls__Vclpkg %000001 if (m_toggle) begin // CHECK_COVER(0,"top.$unit::Cls",1) --000001 point: comment=if --000000 point: comment=else +-000001 point: comment=if hier=top.$unit::Cls__Vclpkg +-000000 point: comment=else hier=top.$unit::Cls__Vclpkg %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.$unit::Cls__Vclpkg end endfunction 000011 static function void fstatic(bit toggle); -+000011 point: comment=block ++000011 point: comment=block hier=top.$unit::Cls__Vclpkg ~000011 if (1) begin // CHECK_COVER(0,"top.$unit::Cls",1) -+000011 point: comment=if --000000 point: comment=else ++000011 point: comment=if hier=top.$unit::Cls__Vclpkg +-000000 point: comment=else hier=top.$unit::Cls__Vclpkg 000011 $write(""); -+000011 point: comment=if ++000011 point: comment=if hier=top.$unit::Cls__Vclpkg end endfunction 000011 function void fauto(); -+000011 point: comment=block ++000011 point: comment=block hier=top.$unit::Cls__Vclpkg ~000011 if (m_toggle) begin // CHECK_COVER(0,"top.$unit::Cls",11) -+000011 point: comment=if --000000 point: comment=else ++000011 point: comment=if hier=top.$unit::Cls__Vclpkg +-000000 point: comment=else hier=top.$unit::Cls__Vclpkg 000011 $write(""); -+000011 point: comment=if ++000011 point: comment=if hier=top.$unit::Cls__Vclpkg end endfunction endclass @@ -295,37 +295,37 @@ /* verilator public_module */ 000010 always @ (posedge clk) begin -+000010 point: comment=block ++000010 point: comment=block hier=top.t.t1 000010 center_task(1'b0); -+000010 point: comment=block ++000010 point: comment=block hier=top.t.t1 end 000011 task center_task; -+000011 point: comment=block ++000011 point: comment=block hier=top.t.t1 input external; 000011 begin -+000011 point: comment=block ++000011 point: comment=block hier=top.t.t1 ~000010 if (toggle) begin // CHECK_COVER(0,"top.t.t1",1) --000001 point: comment=if -+000010 point: comment=else +-000001 point: comment=if hier=top.t.t1 ++000010 point: comment=else hier=top.t.t1 %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.t.t1 end ~000010 if (external) begin // CHECK_COVER(0,"top.t.t1",1) --000001 point: comment=if -+000010 point: comment=else +-000001 point: comment=if hier=top.t.t1 ++000010 point: comment=else hier=top.t.t1 %000001 $write("[%0t] Got external pulse\n", $time); --000001 point: comment=if +-000001 point: comment=if hier=top.t.t1 end end 000011 begin -+000011 point: comment=block ++000011 point: comment=block hier=top.t.t1 %000001 Cls c = new(1'b1); --000001 point: comment=block +-000001 point: comment=block hier=top.t.t1 000011 c.fauto(); -+000011 point: comment=block ++000011 point: comment=block hier=top.t.t1 000011 Cls::fstatic(1'b1); -+000011 point: comment=block ++000011 point: comment=block hier=top.t.t1 end endtask endmodule @@ -346,16 +346,16 @@ end // verilator coverage_on 000010 always @ (posedge clk) begin -+000010 point: comment=block ++000010 point: comment=block hier=top.t.o1 %000009 if (toggle) begin --000001 point: comment=if --000009 point: comment=else +-000001 point: comment=if hier=top.t.o1 +-000009 point: comment=else hier=top.t.o1 // because under coverage_module_off %000001 $write(""); --000001 point: comment=if +-000001 point: comment=if hier=top.t.o1 %000001 if (0) ; // CHECK_COVER(0,"top.t.o1",1) --000000 point: comment=if --000001 point: comment=else +-000000 point: comment=if hier=top.t.o1 +-000001 point: comment=else hier=top.t.o1 end end endmodule @@ -365,28 +365,28 @@ int decoded; 000010 always @ (posedge clk) begin -+000010 point: comment=block ++000010 point: comment=block hier=top.t.tab1 000010 case (cyc4) -+000010 point: comment=block ++000010 point: comment=block hier=top.t.tab1 %000001 1: decoded = 10; --000001 point: comment=case +-000001 point: comment=case hier=top.t.tab1 %000001 2: decoded = 20; --000001 point: comment=case +-000001 point: comment=case hier=top.t.tab1 %000001 3: decoded = 30; --000001 point: comment=case +-000001 point: comment=case hier=top.t.tab1 %000001 4: decoded = 40; --000001 point: comment=case +-000001 point: comment=case hier=top.t.tab1 %000001 5: decoded = 50; --000001 point: comment=case +-000001 point: comment=case hier=top.t.tab1 %000005 default: decoded = 0; --000005 point: comment=case +-000005 point: comment=case hier=top.t.tab1 endcase end 000010 always @ (posedge clk) begin -+000010 point: comment=block ++000010 point: comment=block hier=top.t.tab1 000010 cyc4 <= cyc4 + 1; -+000010 point: comment=block ++000010 point: comment=block hier=top.t.tab1 end endmodule @@ -397,20 +397,20 @@ // seems safer for functions used both at elaboration time and not - but may // revisit this. %000000 function automatic int param_func(int i); --000000 point: comment=block +-000000 point: comment=block hier=top.t.par1 %000000 if (i == 0) begin --000000 point: comment=if --000000 point: comment=else +-000000 point: comment=if hier=top.t.par1 +-000000 point: comment=else hier=top.t.par1 %000000 i = 99; // Uncovered --000000 point: comment=if +-000000 point: comment=if hier=top.t.par1 end %000000 else begin --000000 point: comment=else +-000000 point: comment=else hier=top.t.par1 %000000 i = i + 1; --000000 point: comment=else +-000000 point: comment=else hier=top.t.par1 end %000000 return i; --000000 point: comment=block +-000000 point: comment=block hier=top.t.par1 endfunction endmodule diff --git a/test_regress/t/t_cover_toggle_points.out b/test_regress/t/t_cover_toggle_points.out index 2154b19f1..17279cd14 100644 --- a/test_regress/t/t_cover_toggle_points.out +++ b/test_regress/t/t_cover_toggle_points.out @@ -11,11 +11,11 @@ ); 000019 input clk; -+000019 point: comment=clk ++000019 point: comment=clk hier=top.t input real check_real; // Check issue #2741 000021 input real check_array_real [1:0]; -+000021 point: comment=check_array_real[0] -+000021 point: comment=check_array_real[1] ++000021 point: comment=check_array_real[0] hier=top.t ++000021 point: comment=check_array_real[1] hier=top.t input string check_string; // Check issue #2766 typedef struct packed { @@ -27,11 +27,11 @@ } str_t; %000002 reg toggle; initial toggle='0; --000002 point: comment=toggle +-000002 point: comment=toggle hier=top.t %000002 str_t stoggle; initial stoggle='0; --000002 point: comment=stoggle.b --000002 point: comment=stoggle.u.ua +-000002 point: comment=stoggle.b hier=top.t +-000002 point: comment=stoggle.u.ua hier=top.t union { real val1; // TODO use bit [7:0] here @@ -41,23 +41,23 @@ const reg aconst = '0; %000002 reg [1:0][1:0] ptoggle; initial ptoggle=0; --000002 point: comment=ptoggle[0][0] --000000 point: comment=ptoggle[0][1] --000000 point: comment=ptoggle[1][0] --000000 point: comment=ptoggle[1][1] +-000002 point: comment=ptoggle[0][0] hier=top.t +-000000 point: comment=ptoggle[0][1] hier=top.t +-000000 point: comment=ptoggle[1][0] hier=top.t +-000000 point: comment=ptoggle[1][1] hier=top.t integer cyc; initial cyc=1; ~000011 wire [7:0] cyc_copy = cyc[7:0]; -+000011 point: comment=cyc_copy[0] --000005 point: comment=cyc_copy[1] --000002 point: comment=cyc_copy[2] --000001 point: comment=cyc_copy[3] --000000 point: comment=cyc_copy[4] --000000 point: comment=cyc_copy[5] --000000 point: comment=cyc_copy[6] --000000 point: comment=cyc_copy[7] ++000011 point: comment=cyc_copy[0] hier=top.t +-000005 point: comment=cyc_copy[1] hier=top.t +-000002 point: comment=cyc_copy[2] hier=top.t +-000001 point: comment=cyc_copy[3] hier=top.t +-000000 point: comment=cyc_copy[4] hier=top.t +-000000 point: comment=cyc_copy[5] hier=top.t +-000000 point: comment=cyc_copy[6] hier=top.t +-000000 point: comment=cyc_copy[7] hier=top.t %000002 wire toggle_up; --000002 point: comment=toggle_up +-000002 point: comment=toggle_up hier=top.t typedef struct { int q[$]; @@ -90,30 +90,30 @@ .toggle (toggle)); %000001 reg [1:0] memory[121:110]; --000001 point: comment=memory[110][0] --000000 point: comment=memory[110][1] --000000 point: comment=memory[111][0] --000000 point: comment=memory[111][1] --000000 point: comment=memory[112][0] --000000 point: comment=memory[112][1] --000000 point: comment=memory[113][0] --000000 point: comment=memory[113][1] --000000 point: comment=memory[114][0] --000000 point: comment=memory[114][1] --000000 point: comment=memory[115][0] --000000 point: comment=memory[115][1] --000000 point: comment=memory[116][0] --000000 point: comment=memory[116][1] --000000 point: comment=memory[117][0] --000000 point: comment=memory[117][1] --000000 point: comment=memory[118][0] --000000 point: comment=memory[118][1] --000000 point: comment=memory[119][0] --000000 point: comment=memory[119][1] --000000 point: comment=memory[120][0] --000000 point: comment=memory[120][1] --000000 point: comment=memory[121][0] --000000 point: comment=memory[121][1] +-000001 point: comment=memory[110][0] hier=top.t +-000000 point: comment=memory[110][1] hier=top.t +-000000 point: comment=memory[111][0] hier=top.t +-000000 point: comment=memory[111][1] hier=top.t +-000000 point: comment=memory[112][0] hier=top.t +-000000 point: comment=memory[112][1] hier=top.t +-000000 point: comment=memory[113][0] hier=top.t +-000000 point: comment=memory[113][1] hier=top.t +-000000 point: comment=memory[114][0] hier=top.t +-000000 point: comment=memory[114][1] hier=top.t +-000000 point: comment=memory[115][0] hier=top.t +-000000 point: comment=memory[115][1] hier=top.t +-000000 point: comment=memory[116][0] hier=top.t +-000000 point: comment=memory[116][1] hier=top.t +-000000 point: comment=memory[117][0] hier=top.t +-000000 point: comment=memory[117][1] hier=top.t +-000000 point: comment=memory[118][0] hier=top.t +-000000 point: comment=memory[118][1] hier=top.t +-000000 point: comment=memory[119][0] hier=top.t +-000000 point: comment=memory[119][1] hier=top.t +-000000 point: comment=memory[120][0] hier=top.t +-000000 point: comment=memory[120][1] hier=top.t +-000000 point: comment=memory[121][0] hier=top.t +-000000 point: comment=memory[121][1] hier=top.t wire [1023:0] largeish = {992'h0, cyc}; // CHECK_COVER_MISSING(-1) @@ -154,22 +154,22 @@ // t.a1 and t.a2 collapse to a count of 2 000038 input clk; -+000038 point: comment=clk ++000038 point: comment=clk hier=top.t.a* %000004 input toggle; --000004 point: comment=toggle +-000004 point: comment=toggle hier=top.t.a* // CHECK_COVER(-1,"top.t.a*",4) // 2 edges * (t.a1 and t.a2) ~000022 input [7:0] cyc_copy; -+000022 point: comment=cyc_copy[0] -+000010 point: comment=cyc_copy[1] --000004 point: comment=cyc_copy[2] --000002 point: comment=cyc_copy[3] --000000 point: comment=cyc_copy[4] --000000 point: comment=cyc_copy[5] --000000 point: comment=cyc_copy[6] --000000 point: comment=cyc_copy[7] ++000022 point: comment=cyc_copy[0] hier=top.t.a* ++000010 point: comment=cyc_copy[1] hier=top.t.a* +-000004 point: comment=cyc_copy[2] hier=top.t.a* +-000002 point: comment=cyc_copy[3] hier=top.t.a* +-000000 point: comment=cyc_copy[4] hier=top.t.a* +-000000 point: comment=cyc_copy[5] hier=top.t.a* +-000000 point: comment=cyc_copy[6] hier=top.t.a* +-000000 point: comment=cyc_copy[7] hier=top.t.a* // CHECK_COVER(-1,"top.t.a*","cyc_copy[0]",22) // CHECK_COVER(-2,"top.t.a*","cyc_copy[1]",10) // CHECK_COVER(-3,"top.t.a*","cyc_copy[2]",4) @@ -180,12 +180,12 @@ // CHECK_COVER(-8,"top.t.a*","cyc_copy[7]",0) %000004 reg toggle_internal; --000004 point: comment=toggle_internal +-000004 point: comment=toggle_internal hier=top.t.a* // CHECK_COVER(-1,"top.t.a*",4) // 2 edges * (t.a1 and t.a2) %000004 output reg toggle_up; --000004 point: comment=toggle_up +-000004 point: comment=toggle_up hier=top.t.a* // CHECK_COVER(-1,"top.t.a*",4) // 2 edges * (t.a1 and t.a2) @@ -201,10 +201,10 @@ ); 000019 input clk; -+000019 point: comment=clk ++000019 point: comment=clk hier=top.t.b1 %000002 input toggle_up; --000002 point: comment=toggle_up +-000002 point: comment=toggle_up hier=top.t.b1 // CHECK_COVER(-1,"top.t.b1","toggle_up",2) /* verilator public_module */ @@ -225,7 +225,7 @@ // verilator coverage_on %000002 input toggle; --000002 point: comment=toggle +-000002 point: comment=toggle hier=top.t.o1 // CHECK_COVER(-1,"top.t.o1","toggle",2) endmodule From f458951b17e75283cb72da75687142e832bac8c4 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 1 Nov 2024 14:10:44 +0000 Subject: [PATCH 006/171] Fix slow unsized number parsing (#5577) Try to avoid allocating and deallocating a full --max-num-width buffer on parsing every single unsized number literal. --- src/V3Number.cpp | 7 ++++- .../t/t_const_number_unsized_parse.py | 27 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_const_number_unsized_parse.py diff --git a/src/V3Number.cpp b/src/V3Number.cpp index c446947aa..7f02d7b1e 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -198,7 +198,12 @@ void V3Number::create(const char* sourcep) { } // Otherwise... else if (!sized()) { - width(v3Global.opt.maxNumWidth(), false); // Will change width below + // We don't use v3Global.opt.maxNumWidth() here, as it can be arbitrarily large, + // and cause extremely slow parsing. We will resize the value at the end anyway. + // We just need a width big enough to fit the constant, so we use a conservative + // upper bound to start from. Should never need more than 4 bits per digit. + const int widthBound = std::max(32, std::strlen(value_startp) * 4); + width(widthBound, false); // Will change width below if (unbased) isSigned(true); // Also says the spec. } diff --git a/test_regress/t/t_const_number_unsized_parse.py b/test_regress/t/t_const_number_unsized_parse.py new file mode 100755 index 000000000..c33ca7d69 --- /dev/null +++ b/test_regress/t/t_const_number_unsized_parse.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import signal +import vltest_bootstrap + +test.scenarios('vlt') + +test.top_filename = f"{test.obj_dir}/in.v" + +with open(test.top_filename, "w", encoding="utf8") as f: + f.write("module top;\n") + for i in range(100000): + f.write(f" int x{i} = 'd{i};\n") + f.write("endmodule\n") + +signal.alarm(20) # 20s timeout + +test.lint(verilator_flags2=[f"--max-num-width {2**30}"]) + +test.passes() From aac01868716dca658f6e0044421741f30b3aea2e Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 1 Nov 2024 15:27:08 +0000 Subject: [PATCH 007/171] Fix pylint 3.2.7 global-variable-not-assigned (#5578) --- test_regress/driver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_regress/driver.py b/test_regress/driver.py index 8f8149948..e3b233bc3 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -48,6 +48,8 @@ test = None Arg_Tests = [] Quitting = False Vltmt_Threads = 3 +forker = None +Start = None # So an 'import vltest_bootstrap' inside test files will do nothing sys.modules['vltest_bootstrap'] = {} @@ -2692,7 +2694,6 @@ if __name__ == '__main__': sys.exit("%Error: TEST_REGRESS environment variable is already set") os.environ['TEST_REGRESS'] = os.getcwd() - forker = None Start = time.time() _Parameter_Next_Level = None From 9689a4f58a09cf8c3f9094085a8243b8db4b0ded Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 31 Oct 2024 21:29:13 -0400 Subject: [PATCH 008/171] Internals: Support VL_UNREACHABLE in C++23/MSVC. No functional change intended. --- include/verilatedos.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/include/verilatedos.h b/include/verilatedos.h index 6cb83732f..f633a0f32 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -67,11 +67,21 @@ # endif # define VL_LIKELY(x) __builtin_expect(!!(x), 1) // Prefer over C++20 [[likely]] # define VL_UNLIKELY(x) __builtin_expect(!!(x), 0) // Prefer over C++20 [[unlikely]] -# define VL_UNREACHABLE __builtin_unreachable() // C++23 std::unreachable() # define VL_PREFETCH_RD(p) __builtin_prefetch((p), 0) # define VL_PREFETCH_RW(p) __builtin_prefetch((p), 1) #endif +#ifdef __cpp_lib_unreachable +/// Statement that may never be reached (for coverage etc) +# define VL_UNREACHABLE std::unreachable() // C++23 +#elif defined(__GNUC__) +# define VL_UNREACHABLE __builtin_unreachable() +#elif defined(_MSC_VER) // MSVC +# define VL_UNREACHABLE __assume(false) +#else +# define VL_UNREACHABLE +#endif + // Function acquires a capability/lock (-fthread-safety) #define VL_ACQUIRE(...) \ VL_CLANG_ATTR(annotate("ACQUIRE")) \ @@ -179,9 +189,6 @@ #endif /// Boolean expression never hit by users (branch coverage disabled) # define VL_UNCOVERABLE(x) VL_UNLIKELY(x) -#ifndef VL_UNREACHABLE -# define VL_UNREACHABLE ///< Statement that may never be reached (for coverage etc) -#endif #ifndef VL_PREFETCH_RD # define VL_PREFETCH_RD(p) ///< Prefetch pointer argument with read intent #endif From b097cec72d3cc67da23bece6fd9f5395460b1a1e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 1 Nov 2024 12:39:29 -0400 Subject: [PATCH 009/171] Tests: Reduce false t_const_number_unsized_parse timeouts (#5577) --- test_regress/t/t_const_number_unsized_parse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test_regress/t/t_const_number_unsized_parse.py b/test_regress/t/t_const_number_unsized_parse.py index c33ca7d69..6b8b2c82e 100755 --- a/test_regress/t/t_const_number_unsized_parse.py +++ b/test_regress/t/t_const_number_unsized_parse.py @@ -16,12 +16,12 @@ test.top_filename = f"{test.obj_dir}/in.v" with open(test.top_filename, "w", encoding="utf8") as f: f.write("module top;\n") - for i in range(100000): + for i in range(50000): f.write(f" int x{i} = 'd{i};\n") f.write("endmodule\n") -signal.alarm(20) # 20s timeout +signal.alarm(30) # 30s timeout -test.lint(verilator_flags2=[f"--max-num-width {2**30}"]) +test.lint(verilator_flags2=[f"--max-num-width {2**29}"]) test.passes() From 76b4c2f2548d3a8ad2315c52ed34602b539756f4 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Fri, 1 Nov 2024 17:14:17 +0000 Subject: [PATCH 010/171] driver.py: Properly detect cfg with ccache (#5579) --- test_regress/driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_regress/driver.py b/test_regress/driver.py index e3b233bc3..0a4bc0610 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -2412,7 +2412,7 @@ class VlTest: if VlTest._cached_cfg_with_ccache is None: mkf = VlTest._file_contents_static(os.environ['VERILATOR_ROOT'] + "/include/verilated.mk") - VlTest._cached_cfg_with_ccache = bool(re.match(r'OBJCACHE \?= ccache', mkf)) + VlTest._cached_cfg_with_ccache = bool(re.search(r'OBJCACHE \?= ccache', mkf)) return VlTest._cached_cfg_with_ccache def glob_some(self, pattern: str) -> list: From 589612f9145965e22bfb8d6d1af4307025216587 Mon Sep 17 00:00:00 2001 From: Zhou Shen <599239118@qq.com> Date: Sat, 2 Nov 2024 21:42:57 +0800 Subject: [PATCH 011/171] Fix can't locate scope error in interface task delayed assignment (#5462) (#5568) --- src/V3Fork.cpp | 3 +- src/V3LinkParse.cpp | 2 + test_regress/t/t_json_only_debugcheck.out | 2 +- test_regress/t/t_json_only_first.out | 14 +++---- test_regress/t/t_json_only_flat.out | 18 ++++----- .../t/t_json_only_flat_no_inline_mod.out | 6 +-- test_regress/t/t_json_only_flat_pub_mod.out | 6 +-- test_regress/t/t_json_only_flat_vlvbound.out | 16 ++++---- test_regress/t/t_json_only_output.out | 2 +- test_regress/t/t_json_only_tag.out | 6 +-- test_regress/t/t_var_port_json_only.out | 38 +++++++++---------- .../t/t_var_static_assign_decl_bad.out | 4 ++ test_regress/t/t_varref_scope_in_interface.py | 16 ++++++++ test_regress/t/t_varref_scope_in_interface.v | 22 +++++++++++ 14 files changed, 99 insertions(+), 56 deletions(-) create mode 100755 test_regress/t/t_varref_scope_in_interface.py create mode 100755 test_regress/t/t_varref_scope_in_interface.v diff --git a/src/V3Fork.cpp b/src/V3Fork.cpp index 4f0a6490c..aa9aafff4 100644 --- a/src/V3Fork.cpp +++ b/src/V3Fork.cpp @@ -644,8 +644,7 @@ class ForkVisitor final : public VNVisitor { if (m_forkDepth && !nodep->varp()->isFuncLocal() && nodep->varp()->isClassMember()) return; if (m_forkDepth && (m_forkLocalsp.count(nodep->varp()) == 0) - && nodep->varp()->varType() != VVarType::PORT // Basically static, so it's safe - && !nodep->varp()->lifetime().isStatic()) { + && !nodep->varp()->lifetime().isStatic()) { // Basically static, so it's safe if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())) { nodep->v3warn( diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index faa31fe0c..8e4657d7b 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -299,6 +299,8 @@ class LinkParseVisitor final : public VNVisitor { if (nodep->lifetime().isNone()) nodep->lifetime(m_lifetime); } else if (m_ftaskp) { nodep->lifetime(VLifetime::AUTOMATIC); + } else if (nodep->lifetime().isNone()) { // lifetime shouldn't be unknown, set static if none + nodep->lifetime(VLifetime::STATIC); } if (nodep->isGParam() && !nodep->isAnsi()) { // shadow some parameters into localparams diff --git a/test_regress/t/t_json_only_debugcheck.out b/test_regress/t/t_json_only_debugcheck.out index 2cc666c9a..d8f2eeb9a 100644 --- a/test_regress/t/t_json_only_debugcheck.out +++ b/test_regress/t/t_json_only_debugcheck.out @@ -2,7 +2,7 @@ "modulesp": [ {"type":"MODULE","name":"$root","addr":"(I)","loc":"d,11:8,11:9","origName":"$root","level":1,"modPublic":true,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"clk","addr":"(J)","loc":"d,15:10,15:13","dtypep":"(K)","origName":"clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":true,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"clker","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk","addr":"(J)","loc":"d,15:10,15:13","dtypep":"(K)","origName":"clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":true,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"clker","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.e","addr":"(L)","loc":"d,24:9,24:10","dtypep":"(M)","origName":"e","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"VAR","dtypeName":"my_t","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__Vtrigprevexpr___TOP__clk__0","addr":"(N)","loc":"d,11:8,11:9","dtypep":"(K)","origName":"__Vtrigprevexpr___TOP__clk__0","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"__VactContinue","addr":"(O)","loc":"d,11:8,11:9","dtypep":"(P)","origName":"__VactContinue","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":true,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MODULETEMP","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, diff --git a/test_regress/t/t_json_only_first.out b/test_regress/t/t_json_only_first.out index 67f9fa721..4be43ef77 100644 --- a/test_regress/t/t_json_only_first.out +++ b/test_regress/t/t_json_only_first.out @@ -3,8 +3,8 @@ {"type":"MODULE","name":"t","addr":"(E)","loc":"d,7:8,7:9","origName":"t","level":2,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ {"type":"VAR","name":"q","addr":"(F)","loc":"d,15:22,15:23","dtypep":"(G)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"clk","addr":"(H)","loc":"d,13:10,13:13","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"d","addr":"(J)","loc":"d,14:16,14:17","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk","addr":"(H)","loc":"d,13:10,13:13","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"d","addr":"(J)","loc":"d,14:16,14:17","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"between","addr":"(K)","loc":"d,17:22,17:29","dtypep":"(G)","origName":"between","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"CELL","name":"cell1","addr":"(L)","loc":"d,20:4,20:9","origName":"cell1","recursive":false,"modp":"(M)", "pinsp": [ @@ -39,8 +39,8 @@ ],"activesp": []}, {"type":"MODULE","name":"mod2","addr":"(X)","loc":"d,46:8,46:12","origName":"mod2","level":3,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"clk","addr":"(FB)","loc":"d,48:10,48:13","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"d","addr":"(Z)","loc":"d,49:16,49:17","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk","addr":"(FB)","loc":"d,48:10,48:13","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"d","addr":"(Z)","loc":"d,49:16,49:17","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"q","addr":"(CB)","loc":"d,50:22,50:23","dtypep":"(G)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"ASSIGNW","name":"","addr":"(HB)","loc":"d,53:13,53:14","dtypep":"(G)", "rhsp": [ @@ -56,9 +56,9 @@ "valuep": [ {"type":"CONST","name":"32'sh4","addr":"(MB)","loc":"d,19:18,19:19","dtypep":"(LB)"} ],"attrsp": []}, - {"type":"VAR","name":"clk","addr":"(R)","loc":"d,34:24,34:27","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"d","addr":"(U)","loc":"d,35:30,35:31","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"q","addr":"(O)","loc":"d,36:30,36:31","dtypep":"(G)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk","addr":"(R)","loc":"d,34:24,34:27","dtypep":"(I)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"d","addr":"(U)","loc":"d,35:30,35:31","dtypep":"(G)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"q","addr":"(O)","loc":"d,36:30,36:31","dtypep":"(G)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"IGNORED","addr":"(NB)","loc":"d,39:15,39:22","dtypep":"(LB)","origName":"IGNORED","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"LPARAM","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":true,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh1","addr":"(OB)","loc":"d,39:25,39:26","dtypep":"(LB)"} diff --git a/test_regress/t/t_json_only_flat.out b/test_regress/t/t_json_only_flat.out index d50bd17e5..7159c2b8e 100644 --- a/test_regress/t/t_json_only_flat.out +++ b/test_regress/t/t_json_only_flat.out @@ -3,25 +3,25 @@ {"type":"MODULE","name":"$root","addr":"(F)","loc":"d,7:8,7:9","origName":"$root","level":1,"modPublic":true,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ {"type":"VAR","name":"q","addr":"(G)","loc":"d,15:22,15:23","dtypep":"(H)","origName":"q","isSc":false,"isPrimaryIO":true,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"clk","addr":"(I)","loc":"d,13:10,13:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"clker","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"d","addr":"(K)","loc":"d,14:16,14:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk","addr":"(I)","loc":"d,13:10,13:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"clker","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"d","addr":"(K)","loc":"d,14:16,14:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.q","addr":"(L)","loc":"d,15:22,15:23","dtypep":"(H)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.clk","addr":"(M)","loc":"d,13:10,13:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.d","addr":"(N)","loc":"d,14:16,14:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.clk","addr":"(M)","loc":"d,13:10,13:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.d","addr":"(N)","loc":"d,14:16,14:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.between","addr":"(O)","loc":"d,17:22,17:29","dtypep":"(H)","origName":"between","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.cell1.WIDTH","addr":"(P)","loc":"d,32:15,32:20","dtypep":"(Q)","origName":"WIDTH","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"GPARAM","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":true,"isParam":true,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh4","addr":"(R)","loc":"d,19:18,19:19","dtypep":"(Q)"} ],"attrsp": []}, - {"type":"VAR","name":"t.cell1.clk","addr":"(S)","loc":"d,34:24,34:27","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cell1.d","addr":"(T)","loc":"d,35:30,35:31","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cell1.q","addr":"(U)","loc":"d,36:30,36:31","dtypep":"(H)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cell1.clk","addr":"(S)","loc":"d,34:24,34:27","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cell1.d","addr":"(T)","loc":"d,35:30,35:31","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cell1.q","addr":"(U)","loc":"d,36:30,36:31","dtypep":"(H)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.cell1.IGNORED","addr":"(V)","loc":"d,39:15,39:22","dtypep":"(Q)","origName":"IGNORED","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"LPARAM","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":true,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [], "valuep": [ {"type":"CONST","name":"32'sh1","addr":"(W)","loc":"d,39:25,39:26","dtypep":"(Q)"} ],"attrsp": []}, - {"type":"VAR","name":"t.cell2.clk","addr":"(X)","loc":"d,48:10,48:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"t.cell2.d","addr":"(Y)","loc":"d,49:16,49:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cell2.clk","addr":"(X)","loc":"d,48:10,48:13","dtypep":"(J)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"t.cell2.d","addr":"(Y)","loc":"d,49:16,49:17","dtypep":"(H)","origName":"d","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"t.cell2.q","addr":"(Z)","loc":"d,50:22,50:23","dtypep":"(H)","origName":"q","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"TOPSCOPE","name":"","addr":"(E)","loc":"d,7:8,7:9","senTreesp": [], "scopep": [ diff --git a/test_regress/t/t_json_only_flat_no_inline_mod.out b/test_regress/t/t_json_only_flat_no_inline_mod.out index 9740d57fb..1c177751a 100644 --- a/test_regress/t/t_json_only_flat_no_inline_mod.out +++ b/test_regress/t/t_json_only_flat_no_inline_mod.out @@ -2,9 +2,9 @@ "modulesp": [ {"type":"MODULE","name":"$root","addr":"(F)","loc":"d,11:8,11:11","origName":"$root","level":1,"modPublic":true,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"i_clk","addr":"(G)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"top.i_clk","addr":"(I)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"top.f.i_clk","addr":"(J)","loc":"d,7:24,7:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"i_clk","addr":"(G)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"top.i_clk","addr":"(I)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"top.f.i_clk","addr":"(J)","loc":"d,7:24,7:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"TOPSCOPE","name":"","addr":"(E)","loc":"d,11:8,11:11","senTreesp": [], "scopep": [ {"type":"SCOPE","name":"TOP","addr":"(K)","loc":"d,11:8,11:11","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(F)", diff --git a/test_regress/t/t_json_only_flat_pub_mod.out b/test_regress/t/t_json_only_flat_pub_mod.out index 9740d57fb..1c177751a 100644 --- a/test_regress/t/t_json_only_flat_pub_mod.out +++ b/test_regress/t/t_json_only_flat_pub_mod.out @@ -2,9 +2,9 @@ "modulesp": [ {"type":"MODULE","name":"$root","addr":"(F)","loc":"d,11:8,11:11","origName":"$root","level":1,"modPublic":true,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"i_clk","addr":"(G)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"top.i_clk","addr":"(I)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"top.f.i_clk","addr":"(J)","loc":"d,7:24,7:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"i_clk","addr":"(G)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"top.i_clk","addr":"(I)","loc":"d,11:24,11:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"top.f.i_clk","addr":"(J)","loc":"d,7:24,7:29","dtypep":"(H)","origName":"i_clk","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"TOPSCOPE","name":"","addr":"(E)","loc":"d,11:8,11:11","senTreesp": [], "scopep": [ {"type":"SCOPE","name":"TOP","addr":"(K)","loc":"d,11:8,11:11","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(F)", diff --git a/test_regress/t/t_json_only_flat_vlvbound.out b/test_regress/t/t_json_only_flat_vlvbound.out index eea5a88fa..9745e13a3 100644 --- a/test_regress/t/t_json_only_flat_vlvbound.out +++ b/test_regress/t/t_json_only_flat_vlvbound.out @@ -2,14 +2,14 @@ "modulesp": [ {"type":"MODULE","name":"$root","addr":"(F)","loc":"d,7:8,7:21","origName":"$root","level":1,"modPublic":true,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"i_a","addr":"(G)","loc":"d,9:25,9:28","dtypep":"(H)","origName":"i_a","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"i_b","addr":"(I)","loc":"d,10:25,10:28","dtypep":"(H)","origName":"i_b","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"o_a","addr":"(J)","loc":"d,11:25,11:28","dtypep":"(K)","origName":"o_a","isSc":false,"isPrimaryIO":true,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"o_b","addr":"(L)","loc":"d,12:25,12:28","dtypep":"(K)","origName":"o_b","isSc":false,"isPrimaryIO":true,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"vlvbound_test.i_a","addr":"(M)","loc":"d,9:25,9:28","dtypep":"(H)","origName":"i_a","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"vlvbound_test.i_b","addr":"(N)","loc":"d,10:25,10:28","dtypep":"(H)","origName":"i_b","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"vlvbound_test.o_a","addr":"(O)","loc":"d,11:25,11:28","dtypep":"(K)","origName":"o_a","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"vlvbound_test.o_b","addr":"(P)","loc":"d,12:25,12:28","dtypep":"(K)","origName":"o_b","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"i_a","addr":"(G)","loc":"d,9:25,9:28","dtypep":"(H)","origName":"i_a","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"i_b","addr":"(I)","loc":"d,10:25,10:28","dtypep":"(H)","origName":"i_b","isSc":false,"isPrimaryIO":true,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"o_a","addr":"(J)","loc":"d,11:25,11:28","dtypep":"(K)","origName":"o_a","isSc":false,"isPrimaryIO":true,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"o_b","addr":"(L)","loc":"d,12:25,12:28","dtypep":"(K)","origName":"o_b","isSc":false,"isPrimaryIO":true,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":true,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"vlvbound_test.i_a","addr":"(M)","loc":"d,9:25,9:28","dtypep":"(H)","origName":"i_a","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"vlvbound_test.i_b","addr":"(N)","loc":"d,10:25,10:28","dtypep":"(H)","origName":"i_b","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"vlvbound_test.o_a","addr":"(O)","loc":"d,11:25,11:28","dtypep":"(K)","origName":"o_a","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"vlvbound_test.o_b","addr":"(P)","loc":"d,12:25,12:28","dtypep":"(K)","origName":"o_b","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"TOPSCOPE","name":"","addr":"(E)","loc":"d,7:8,7:21","senTreesp": [], "scopep": [ {"type":"SCOPE","name":"TOP","addr":"(Q)","loc":"d,7:8,7:21","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(F)", diff --git a/test_regress/t/t_json_only_output.out b/test_regress/t/t_json_only_output.out index 781242642..bb3109dc7 100644 --- a/test_regress/t/t_json_only_output.out +++ b/test_regress/t/t_json_only_output.out @@ -2,7 +2,7 @@ "modulesp": [ {"type":"MODULE","name":"m","addr":"(E)","loc":"d,7:8,7:9","origName":"m","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"clk","addr":"(F)","loc":"d,8:10,8:13","dtypep":"(G)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"clk","addr":"(F)","loc":"d,8:10,8:13","dtypep":"(G)","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []} ],"filesp": [], "miscsp": [ diff --git a/test_regress/t/t_json_only_tag.out b/test_regress/t/t_json_only_tag.out index edadeff67..393a928fa 100644 --- a/test_regress/t/t_json_only_tag.out +++ b/test_regress/t/t_json_only_tag.out @@ -2,9 +2,9 @@ "modulesp": [ {"type":"MODULE","name":"m","addr":"(E)","loc":"d,12:8,12:9","origName":"m","level":2,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"clk_ip","addr":"(F)","loc":"d,14:11,14:17","dtypep":"(G)","origName":"clk_ip","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"rst_ip","addr":"(H)","loc":"d,15:11,15:17","dtypep":"(G)","origName":"rst_ip","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"foo_op","addr":"(I)","loc":"d,16:11,16:17","dtypep":"(G)","origName":"foo_op","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"clk_ip","addr":"(F)","loc":"d,14:11,14:17","dtypep":"(G)","origName":"clk_ip","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"rst_ip","addr":"(H)","loc":"d,15:11,15:17","dtypep":"(G)","origName":"rst_ip","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"foo_op","addr":"(I)","loc":"d,16:11,16:17","dtypep":"(G)","origName":"foo_op","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"TYPEDEF","name":"my_struct","addr":"(J)","loc":"d,25:6,25:15","dtypep":"(K)","attrPublic":false,"childDTypep": [],"attrsp": []}, {"type":"CELL","name":"itop","addr":"(L)","loc":"d,29:8,29:12","origName":"itop","recursive":false,"modp":"(M)","pinsp": [],"paramsp": [],"rangep": [],"intfRefsp": []}, {"type":"VAR","name":"itop__Viftop","addr":"(N)","loc":"d,29:8,29:12","dtypep":"(O)","origName":"itop__Viftop","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"IFACEREF","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, diff --git a/test_regress/t/t_var_port_json_only.out b/test_regress/t/t_var_port_json_only.out index 0b45d1513..f136884c5 100644 --- a/test_regress/t/t_var_port_json_only.out +++ b/test_regress/t/t_var_port_json_only.out @@ -2,68 +2,68 @@ "modulesp": [ {"type":"MODULE","name":"mh2","addr":"(E)","loc":"d,18:8,18:11","origName":"mh2","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_inout_wire_integer","addr":"(F)","loc":"d,18:27,18:47","dtypep":"(G)","origName":"x_inout_wire_integer","isSc":false,"isPrimaryIO":false,"direction":"INOUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_inout_wire_integer","addr":"(F)","loc":"d,18:27,18:47","dtypep":"(G)","origName":"x_inout_wire_integer","isSc":false,"isPrimaryIO":false,"direction":"INOUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh5","addr":"(H)","loc":"d,24:8,24:11","origName":"mh5","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_input_wire_logic","addr":"(I)","loc":"d,24:19,24:37","dtypep":"(J)","origName":"x_input_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_input_wire_logic","addr":"(I)","loc":"d,24:19,24:37","dtypep":"(J)","origName":"x_input_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh6","addr":"(K)","loc":"d,26:8,26:11","origName":"mh6","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_input_var_logic","addr":"(L)","loc":"d,26:23,26:40","dtypep":"(J)","origName":"x_input_var_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_input_var_logic","addr":"(L)","loc":"d,26:23,26:40","dtypep":"(J)","origName":"x_input_var_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh7","addr":"(M)","loc":"d,28:8,28:11","origName":"mh7","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_input_var_integer","addr":"(N)","loc":"d,28:31,28:50","dtypep":"(G)","origName":"x_input_var_integer","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_input_var_integer","addr":"(N)","loc":"d,28:31,28:50","dtypep":"(G)","origName":"x_input_var_integer","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh8","addr":"(O)","loc":"d,30:8,30:11","origName":"mh8","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_wire_logic","addr":"(P)","loc":"d,30:20,30:39","dtypep":"(J)","origName":"x_output_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_wire_logic","addr":"(P)","loc":"d,30:20,30:39","dtypep":"(J)","origName":"x_output_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh9","addr":"(Q)","loc":"d,32:8,32:11","origName":"mh9","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_var_logic","addr":"(R)","loc":"d,32:24,32:42","dtypep":"(J)","origName":"x_output_var_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_var_logic","addr":"(R)","loc":"d,32:24,32:42","dtypep":"(J)","origName":"x_output_var_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh10","addr":"(S)","loc":"d,34:8,34:12","origName":"mh10","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_wire_logic_signed_p6","addr":"(T)","loc":"d,34:33,34:62","dtypep":"(U)","origName":"x_output_wire_logic_signed_p6","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_wire_logic_signed_p6","addr":"(T)","loc":"d,34:33,34:62","dtypep":"(U)","origName":"x_output_wire_logic_signed_p6","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh11","addr":"(V)","loc":"d,36:8,36:12","origName":"mh11","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_var_integer","addr":"(W)","loc":"d,36:28,36:48","dtypep":"(G)","origName":"x_output_var_integer","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_var_integer","addr":"(W)","loc":"d,36:28,36:48","dtypep":"(G)","origName":"x_output_var_integer","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh12","addr":"(X)","loc":"d,38:8,38:12","origName":"mh12","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_ref_logic_p6","addr":"(Y)","loc":"d,38:23,38:37","dtypep":"(Z)","origName":"x_ref_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_ref_logic_p6","addr":"(Y)","loc":"d,38:23,38:37","dtypep":"(Z)","origName":"x_ref_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh13","addr":"(AB)","loc":"d,40:8,40:12","origName":"mh13","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_ref_var_logic_u6","addr":"(BB)","loc":"d,40:17,40:35","dtypep":"(CB)","origName":"x_ref_var_logic_u6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_ref_var_logic_u6","addr":"(BB)","loc":"d,40:17,40:35","dtypep":"(CB)","origName":"x_ref_var_logic_u6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh17","addr":"(DB)","loc":"d,50:8,50:12","origName":"mh17","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_input_var_integer","addr":"(EB)","loc":"d,50:31,50:50","dtypep":"(G)","origName":"x_input_var_integer","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"x_input_var_integer","addr":"(EB)","loc":"d,50:31,50:50","dtypep":"(G)","origName":"x_input_var_integer","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"y_input_wire_logic","addr":"(FB)","loc":"d,50:57,50:75","dtypep":"(J)","origName":"y_input_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"WIRE","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh18","addr":"(GB)","loc":"d,52:8,52:12","origName":"mh18","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_var_logic","addr":"(HB)","loc":"d,52:24,52:42","dtypep":"(J)","origName":"x_output_var_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"y_input_wire_logic","addr":"(IB)","loc":"d,52:50,52:68","dtypep":"(J)","origName":"y_input_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_var_logic","addr":"(HB)","loc":"d,52:24,52:42","dtypep":"(J)","origName":"x_output_var_logic","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"y_input_wire_logic","addr":"(IB)","loc":"d,52:50,52:68","dtypep":"(J)","origName":"y_input_wire_logic","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh19","addr":"(JB)","loc":"d,54:8,54:12","origName":"mh19","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_output_wire_logic_signed_p6","addr":"(KB)","loc":"d,54:33,54:62","dtypep":"(U)","origName":"x_output_wire_logic_signed_p6","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"y_output_var_integer","addr":"(LB)","loc":"d,54:72,54:92","dtypep":"(G)","origName":"y_output_var_integer","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_output_wire_logic_signed_p6","addr":"(KB)","loc":"d,54:33,54:62","dtypep":"(U)","origName":"x_output_wire_logic_signed_p6","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"y_output_var_integer","addr":"(LB)","loc":"d,54:72,54:92","dtypep":"(G)","origName":"y_output_var_integer","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh20","addr":"(MB)","loc":"d,56:8,56:12","origName":"mh20","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"x_ref_var_logic_p6","addr":"(NB)","loc":"d,56:23,56:41","dtypep":"(Z)","origName":"x_ref_var_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"y_ref_var_logic_p6","addr":"(OB)","loc":"d,56:43,56:61","dtypep":"(Z)","origName":"y_ref_var_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"x_ref_var_logic_p6","addr":"(NB)","loc":"d,56:23,56:41","dtypep":"(Z)","origName":"x_ref_var_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"y_ref_var_logic_p6","addr":"(OB)","loc":"d,56:43,56:61","dtypep":"(Z)","origName":"y_ref_var_logic_p6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []}, {"type":"MODULE","name":"mh21","addr":"(PB)","loc":"d,58:8,58:12","origName":"mh21","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"VAR","name":"ref_var_logic_u6","addr":"(QB)","loc":"d,58:17,58:33","dtypep":"(RB)","origName":"ref_var_logic_u6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"y_ref_var_logic","addr":"(SB)","loc":"d,58:41,58:56","dtypep":"(J)","origName":"y_ref_var_logic","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} + {"type":"VAR","name":"ref_var_logic_u6","addr":"(QB)","loc":"d,58:17,58:33","dtypep":"(RB)","origName":"ref_var_logic_u6","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"VAR","name":"y_ref_var_logic","addr":"(SB)","loc":"d,58:41,58:56","dtypep":"(J)","origName":"y_ref_var_logic","isSc":false,"isPrimaryIO":false,"direction":"REF","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VSTATIC","varType":"PORT","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": []} ],"filesp": [], "miscsp": [ diff --git a/test_regress/t/t_var_static_assign_decl_bad.out b/test_regress/t/t_var_static_assign_decl_bad.out index 7ca2970b1..b296e1482 100644 --- a/test_regress/t/t_var_static_assign_decl_bad.out +++ b/test_regress/t/t_var_static_assign_decl_bad.out @@ -63,4 +63,8 @@ : is dependent on function/task I/O variable 49 | logic tmp = in; | ^~ +%Error-UNSUPPORTED: t/t_var_static_assign_decl_bad.v:72:17: Static variable initializer + : is dependent on function/task I/O variable + 72 | logic tmp = in; + | ^~ %Error: Exiting due to diff --git a/test_regress/t/t_varref_scope_in_interface.py b/test_regress/t/t_varref_scope_in_interface.py new file mode 100755 index 000000000..fbe7b466b --- /dev/null +++ b/test_regress/t/t_varref_scope_in_interface.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=["--lint-only", "--timing"]) + +test.passes() diff --git a/test_regress/t/t_varref_scope_in_interface.v b/test_regress/t/t_varref_scope_in_interface.v new file mode 100755 index 000000000..d030b5c13 --- /dev/null +++ b/test_regress/t/t_varref_scope_in_interface.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface iface #(parameter DWIDTH = 32)(); + localparam TOTAL_PACKED_WIDTH = DWIDTH + 1; + modport Tx(output sop, data, import unpack); + logic sop; + logic [DWIDTH - 1:0] data = '0; + + task static unpack(input logic [TOTAL_PACKED_WIDTH-1:0] packed_in, input logic sop_i); + logic sop_nc; + {data, sop_nc} <= packed_in; + sop <= sop_i; + endtask +endinterface + +module t; +iface ifc(); +endmodule From e1a97349175a4a62e5fc18abff18f360ca2e54b4 Mon Sep 17 00:00:00 2001 From: github action Date: Sat, 2 Nov 2024 13:43:43 +0000 Subject: [PATCH 012/171] Apply 'make format' --- src/V3LinkParse.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 8e4657d7b..123716fb2 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -299,7 +299,8 @@ class LinkParseVisitor final : public VNVisitor { if (nodep->lifetime().isNone()) nodep->lifetime(m_lifetime); } else if (m_ftaskp) { nodep->lifetime(VLifetime::AUTOMATIC); - } else if (nodep->lifetime().isNone()) { // lifetime shouldn't be unknown, set static if none + } else if (nodep->lifetime() + .isNone()) { // lifetime shouldn't be unknown, set static if none nodep->lifetime(VLifetime::STATIC); } From ed0e1af7aa339eb677c1c6f19c8c5f07e739f8aa Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 2 Nov 2024 09:47:55 -0400 Subject: [PATCH 013/171] Commentary: Changes update --- Changes | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Changes b/Changes index 4ded496a4..6662cfff7 100644 --- a/Changes +++ b/Changes @@ -11,6 +11,14 @@ contributors that suggested a given feature are shown in []. Thanks! Verilator 5.031 devel ========================== +**Minor:** + +* Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] +* Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] +* Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] +* Fix --output-groups leftover files issue (#5574). [Todd Strader] +* Fix slow unsized number parsing (#5577). [Geza Lore] Verilator 5.030 2024-10-27 From 7854118883cdce48124cb92962f9a27626e2345a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 2 Nov 2024 10:06:01 -0400 Subject: [PATCH 014/171] Fix negative assignment pattern keys (#5580). --- Changes | 1 + src/verilog.y | 17 ++++++++++++----- test_regress/t/t_array_pattern_2d.v | 7 +++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Changes b/Changes index 6662cfff7..2c76dba5e 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,7 @@ Verilator 5.031 devel * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] * Fix --output-groups leftover files issue (#5574). [Todd Strader] * Fix slow unsized number parsing (#5577). [Geza Lore] +* Fix negative assignment pattern keys (#5580). [Iztok Jeras] Verilator 5.030 2024-10-27 diff --git a/src/verilog.y b/src/verilog.y index 9fbf16bde..0272e2c4d 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4006,11 +4006,18 @@ patternKey: // IEEE: merge structure_pattern_key, array_patt // // "foo"member (if structure) // // So for now we only allow a true constant number, or an // // identifier which we treat as a structure member name - yaINTNUM { $$ = new AstConst{$1, *$1}; } - | yaFLOATNUM { $$ = new AstConst{$1, AstConst::RealDouble{}, $1}; } - | id { $$ = new AstText{$1, *$1}; } - | strAsInt { $$ = $1; } - | simple_typeNoRef { $$ = $1; } + yaINTNUM + { $$ = new AstConst{$1, *$1}; } + | '-' yaINTNUM + { V3Number neg{*$2}; neg.opNegate(*$2); $$ = new AstConst{$2, neg}; } + | yaFLOATNUM + { $$ = new AstConst{$1, AstConst::RealDouble{}, $1}; } + | id + { $$ = new AstText{$1, *$1}; } + | strAsInt + { $$ = $1; } + | simple_typeNoRef + { $$ = $1; } // // expanded from simple_type ps_type_identifier (part of simple_type) // // expanded from simple_type ps_parameter_identifier (part of simple_type) | packageClassScopeE idType diff --git a/test_regress/t/t_array_pattern_2d.v b/test_regress/t/t_array_pattern_2d.v index dba37eef2..051e1f1d8 100644 --- a/test_regress/t/t_array_pattern_2d.v +++ b/test_regress/t/t_array_pattern_2d.v @@ -13,6 +13,8 @@ module t (/*AUTOARG*/); logic [31:0] larray_assign [0:3]; logic [31:0] larray_other [0:3]; + logic [31:0] array_neg [-1:1]; + initial begin array_assign[0] = 32'd1; array_assign[3:1] = '{32'd4, 32'd3, 32'd2}; @@ -34,6 +36,11 @@ module t (/*AUTOARG*/); if (larray_other[2] != 3) $stop; if (larray_other[3] != 2) $stop; + array_neg = '{-1: 5, 1: 7, default: 'd6}; + if (array_neg[-1] != 5) $stop; + if (array_neg[0] != 6) $stop; + if (array_neg[1] != 7) $stop; + $write("*-* All Finished *-*\n"); $finish; end From b3348a38d0e46d468f5fea88abfe7501e04345bc Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Mon, 4 Nov 2024 13:48:55 +0100 Subject: [PATCH 015/171] Internals: Remove repeated clearing of constraints (#5583) Signed-off-by: Ryszard Rozak --- src/V3Randomize.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 49ef24aff..c248c112e 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1883,7 +1883,6 @@ class RandomizeVisitor final : public VNVisitor { AstTask* setupAllTaskp = getCreateConstraintSetupFunc(nodep); AstTaskRef* const setupTaskRefp = new AstTaskRef{fl, setupAllTaskp->name(), nullptr}; setupTaskRefp->taskp(setupAllTaskp); - randomizep->addStmtsp(implementConstraintsClear(fl, genp)); randomizep->addStmtsp(setupTaskRefp->makeStmt()); AstNodeModule* const genModp = VN_AS(genp->user2p(), NodeModule); From 4e71f359bf6c19e603541c0107ffff0d90a85a9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Mon, 4 Nov 2024 15:06:15 +0100 Subject: [PATCH 016/171] Fix duplicate scope identifiers decoding (#5584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bartłomiej Chmiel Co-authored-by: Ryszard Rozak --- src/V3EmitCSyms.cpp | 13 +------------ test_regress/t/t_vpi_escape.cpp | 10 ++++++++++ test_regress/t/t_vpi_escape.v | 4 ++++ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 14323fed6..4198eecc5 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -156,7 +156,6 @@ class EmitCSyms final : EmitCBaseVisitorConst { } static string scopeDecodeIdentifier(const string& scpname) { - string out = scpname; string::size_type pos = string::npos; // Remove hierarchy @@ -172,17 +171,7 @@ class EmitCSyms final : EmitCBaseVisitorConst { } } - if (pos != std::string::npos) out.erase(0, pos + 1); - - // Decode all escaped characters - while ((pos = out.find("__0")) != string::npos) { - unsigned int x; - std::stringstream ss; - ss << std::hex << out.substr(pos + 3, 2); - ss >> x; - out.replace(pos, 5, 1, (char)x); - } - return out; + return pos != string::npos ? scpname.substr(pos + 1) : scpname; } /// (scp, m_vpiScopeCandidates, m_scopeNames) -> m_scopeNames diff --git a/test_regress/t/t_vpi_escape.cpp b/test_regress/t/t_vpi_escape.cpp index 043a62a5d..7fed0d2e6 100644 --- a/test_regress/t/t_vpi_escape.cpp +++ b/test_regress/t/t_vpi_escape.cpp @@ -135,6 +135,16 @@ int _mon_check_iter() { TEST_CHECK_CSTR(p, ""); // Unsupported } + TestVpiHandle vh_null_name = MY_VPI_HANDLE("___0_"); + TEST_CHECK_NZ(vh_null_name); + p = vpi_get_str(vpiName, vh_null_name); + TEST_CHECK_CSTR(p, "___0_"); + + TestVpiHandle vh_hex_name = MY_VPI_HANDLE("___0F_"); + TEST_CHECK_NZ(vh_hex_name); + p = vpi_get_str(vpiName, vh_hex_name); + TEST_CHECK_CSTR(p, "___0F_"); + TestVpiHandle vh10 = vpi_iterate(vpiReg, vh2); TEST_CHECK_NZ(vh10); TEST_CHECK_EQ(vpi_get(vpiType, vh10), vpiIterator); diff --git a/test_regress/t/t_vpi_escape.v b/test_regress/t/t_vpi_escape.v index b575dc199..a912c1096 100644 --- a/test_regress/t/t_vpi_escape.v +++ b/test_regress/t/t_vpi_escape.v @@ -63,6 +63,10 @@ extern "C" int mon_check(); sub \mod.with_dot (.cyc(cyc)); + // Check if scope names are not decoded twice + sub ___0F_ (.cyc(cyc)); + sub ___0_ (.cyc(cyc)); + initial begin `ifdef VERILATOR From eaaf91c82b9aa3874be75cd0ce24546af988d3cf Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 4 Nov 2024 23:55:39 -0500 Subject: [PATCH 017/171] Internals: Cleanup VL_RESTORER format in V3LinkLValue. No functional change. --- src/V3LinkLValue.cpp | 175 ++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 104 deletions(-) diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index e0d14cdfb..ceb7acf8c 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -32,13 +32,15 @@ VL_DEFINE_DEBUG_FUNCTIONS; class LinkLValueVisitor final : public VNVisitor { // NODE STATE - // STATE + // STATE - for current visit position (use VL_RESTORER) bool m_setContinuously = false; // Set that var has some continuous assignment - bool m_setStrengthSpecified = false; // Set that var has assignment with strength specified. bool m_setForcedByCode = false; // Set that var is the target of an AstAssignForce/AstRelease bool m_setIfRand = false; // Update VarRefs if var declared as rand bool m_inInitialStatic = false; // Set if inside AstInitialStatic bool m_inFunc = false; // Set if inside AstNodeFTask + + // STATE - TODO + bool m_setStrengthSpecified = false; // Set that var has assignment with strength specified. VAccess m_setRefLvalue; // Set VarRefs to lvalues for pin assignments // VISITs @@ -137,75 +139,57 @@ class LinkLValueVisitor final : public VNVisitor { VL_RESTORER(m_setRefLvalue); VL_RESTORER(m_setContinuously); VL_RESTORER(m_setForcedByCode); - { - m_setRefLvalue = VAccess::WRITE; - m_setContinuously = false; - m_setForcedByCode = true; - iterateAndNextNull(nodep->lhsp()); - } + m_setRefLvalue = VAccess::WRITE; + m_setContinuously = false; + m_setForcedByCode = true; + iterateAndNextNull(nodep->lhsp()); } void visit(AstFireEvent* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->operandp()); - } + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->operandp()); } void visit(AstCastDynamic* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->fromp()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->top()); - } + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->fromp()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->top()); } void visit(AstFError* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->filep()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->strp()); - } + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->strp()); } void visit(AstFGetS* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->filep()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->strgp()); - } + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->strgp()); } void visit(AstFRead* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->filep()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->memp()); - } + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->memp()); } void visit(AstFScanF* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->filep()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->exprsp()); - } + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->exprsp()); } void visit(AstFUngetC* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->filep()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->rhsp()); - } + iterateAndNextNull(nodep->filep()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->rhsp()); } void visit(AstSScanF* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->exprsp()); - } + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->exprsp()); } void visit(AstSysIgnore* nodep) override { // Can't know if lvalue or not; presume not @@ -213,46 +197,36 @@ class LinkLValueVisitor final : public VNVisitor { } void visit(AstRand* nodep) override { VL_RESTORER(m_setRefLvalue); - { - if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->seedp()); - } + if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->seedp()); } void visit(AstReadMem* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->memp()); - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->filenamep()); - iterateAndNextNull(nodep->lsbp()); - iterateAndNextNull(nodep->msbp()); - } + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->memp()); + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->filenamep()); + iterateAndNextNull(nodep->lsbp()); + iterateAndNextNull(nodep->msbp()); } void visit(AstTestPlusArgs* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->searchp()); - } + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->searchp()); } void visit(AstValuePlusArgs* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->searchp()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->outp()); - } + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->searchp()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->outp()); } void visit(AstSFormat* nodep) override { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->lhsp()); - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->fmtp()); - } + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->lhsp()); + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->fmtp()); } void visit(AstNodeDistBiop* nodep) override { VL_RESTORER(m_setRefLvalue); @@ -271,13 +245,11 @@ class LinkLValueVisitor final : public VNVisitor { } void prepost_visit(AstNodeTriop* nodep) { VL_RESTORER(m_setRefLvalue); - { - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->lhsp()); - iterateAndNextNull(nodep->rhsp()); - m_setRefLvalue = VAccess::WRITE; - iterateAndNextNull(nodep->thsp()); - } + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->lhsp()); + iterateAndNextNull(nodep->rhsp()); + m_setRefLvalue = VAccess::WRITE; + iterateAndNextNull(nodep->thsp()); } void visit(AstPreAdd* nodep) override { prepost_visit(nodep); } void visit(AstPostAdd* nodep) override { prepost_visit(nodep); } @@ -287,38 +259,33 @@ class LinkLValueVisitor final : public VNVisitor { // Nodes that change LValue state void visit(AstSel* nodep) override { VL_RESTORER(m_setRefLvalue); - { - iterateAndNextNull(nodep->fromp()); - // Only set lvalues on the from - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->lsbp()); - iterateAndNextNull(nodep->widthp()); - } + iterateAndNextNull(nodep->fromp()); + // Only set lvalues on the from + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->lsbp()); + iterateAndNextNull(nodep->widthp()); } void visit(AstNodeSel* nodep) override { VL_RESTORER(m_setRefLvalue); - { // Only set lvalues on the from - iterateAndNextNull(nodep->fromp()); - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->bitp()); - } + // Only set lvalues on the from + iterateAndNextNull(nodep->fromp()); + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->bitp()); } void visit(AstCellArrayRef* nodep) override { VL_RESTORER(m_setRefLvalue); - { // selp is not an lvalue - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->selp()); - } + // selp is not an lvalue + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->selp()); } void visit(AstNodePreSel* nodep) override { if (AstSelBit* const selbitp = VN_CAST(nodep, SelBit)) selbitp->access(m_setRefLvalue); VL_RESTORER(m_setRefLvalue); - { // Only set lvalues on the from - iterateAndNextNull(nodep->fromp()); - m_setRefLvalue = VAccess::NOCHANGE; - iterateAndNextNull(nodep->rhsp()); - iterateAndNextNull(nodep->thsp()); - } + // Only set lvalues on the from + iterateAndNextNull(nodep->fromp()); + m_setRefLvalue = VAccess::NOCHANGE; + iterateAndNextNull(nodep->rhsp()); + iterateAndNextNull(nodep->thsp()); } void visit(AstMemberSel* nodep) override { if (m_setRefLvalue != VAccess::NOCHANGE) { From 2e4676dc1102a2fb9876be44e2f18553f1fc552f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 5 Nov 2024 00:03:23 -0500 Subject: [PATCH 018/171] Internals: Add missing VL_RESTORERS to V3LinkLValue; probably fixes no real cases, bug better safe. --- src/V3LinkLValue.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index ceb7acf8c..3cbbcbfd9 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -36,11 +36,9 @@ class LinkLValueVisitor final : public VNVisitor { bool m_setContinuously = false; // Set that var has some continuous assignment bool m_setForcedByCode = false; // Set that var is the target of an AstAssignForce/AstRelease bool m_setIfRand = false; // Update VarRefs if var declared as rand - bool m_inInitialStatic = false; // Set if inside AstInitialStatic - bool m_inFunc = false; // Set if inside AstNodeFTask - - // STATE - TODO bool m_setStrengthSpecified = false; // Set that var has assignment with strength specified. + bool m_inFunc = false; // Set if inside AstNodeFTask + bool m_inInitialStatic = false; // Set if inside AstInitialStatic VAccess m_setRefLvalue; // Set VarRefs to lvalues for pin assignments // VISITs @@ -76,6 +74,7 @@ class LinkLValueVisitor final : public VNVisitor { // Nodes that start propagating down lvalues void visit(AstPin* nodep) override { + VL_RESTORER(m_setRefLvalue); if (nodep->modVarp() && nodep->modVarp()->isWritable()) { // When the varref's were created, we didn't know the I/O state // Now that we do, and it's from a output, we know it's a lvalue @@ -89,6 +88,7 @@ class LinkLValueVisitor final : public VNVisitor { void visit(AstNodeAssign* nodep) override { VL_RESTORER(m_setRefLvalue); VL_RESTORER(m_setContinuously); + VL_RESTORER(m_setStrengthSpecified); { m_setRefLvalue = VAccess::WRITE; m_setContinuously = VN_IS(nodep, AssignW) || VN_IS(nodep, AssignAlias); @@ -317,9 +317,9 @@ class LinkLValueVisitor final : public VNVisitor { AstNodeExpr* const pinp = argp->exprp(); if (!pinp) continue; if (portp->isWritable()) { + VL_RESTORER(m_setRefLvalue); m_setRefLvalue = VAccess::WRITE; iterate(pinp); - m_setRefLvalue = VAccess::NOCHANGE; } else { iterate(pinp); } From b1dfdef0a9b60e59644ec62599eee46c67292d2d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 5 Nov 2024 00:17:40 -0500 Subject: [PATCH 019/171] Add error when improperly storing to parameter (#5147). --- Changes | 1 + src/V3AstNodeOther.h | 10 +++++----- src/V3LinkLValue.cpp | 7 +++++++ test_regress/t/t_param_store_bad.out | 4 ++++ test_regress/t/t_param_store_bad.py | 16 ++++++++++++++++ test_regress/t/t_param_store_bad.v | 18 ++++++++++++++++++ 6 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 test_regress/t/t_param_store_bad.out create mode 100755 test_regress/t/t_param_store_bad.py create mode 100644 test_regress/t/t_param_store_bad.v diff --git a/Changes b/Changes index 2c76dba5e..40b9b157e 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,7 @@ Verilator 5.031 devel **Minor:** * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 8387f70c9..e4b3cee54 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2069,7 +2069,7 @@ public: bool isTristate() const { return m_tristate; } bool isPrimaryIO() const VL_MT_SAFE { return m_primaryIO; } bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } - bool isIfaceRef() const { return (varType() == VVarType::IFACEREF); } + bool isIfaceRef() const { return varType() == VVarType::IFACEREF; } bool isIfaceParent() const { return m_isIfaceParent; } bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } @@ -2085,11 +2085,11 @@ public: && !isSc() && !isPrimaryIO() && !isConst() && !isDouble() && !isString()); } bool isClassMember() const { return varType() == VVarType::MEMBER; } - bool isStatementTemp() const { return (varType() == VVarType::STMTTEMP); } - bool isXTemp() const { return (varType() == VVarType::XTEMP); } + bool isStatementTemp() const { return varType() == VVarType::STMTTEMP; } + bool isXTemp() const { return varType() == VVarType::XTEMP; } bool isParam() const { return varType().isParam(); } - bool isGParam() const { return (varType() == VVarType::GPARAM); } - bool isGenVar() const { return (varType() == VVarType::GENVAR); } + bool isGParam() const { return varType() == VVarType::GPARAM; } + bool isGenVar() const { return varType() == VVarType::GENVAR; } bool isBitLogic() const { AstBasicDType* bdtypep = basicp(); return bdtypep && bdtypep->isBitLogic(); diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 3cbbcbfd9..160d0075e 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -48,6 +48,13 @@ class LinkLValueVisitor final : public VNVisitor { if (m_setIfRand && !(nodep->varp() && nodep->varp()->isRand())) return; if (m_setRefLvalue != VAccess::NOCHANGE) nodep->access(m_setRefLvalue); if (nodep->varp() && nodep->access().isWriteOrRW()) { + if (nodep->varp()->isParam()) { + // All parameters that did get constified happened before now + // as V3LinkLValue runs after V3Param + nodep->v3error("Storing to parameter variable " + << nodep->prettyNameQ() + << " in a context that is determed only at runtime"); + } if (m_setContinuously) { nodep->varp()->isContinuously(true); // Strength may only be specified in continuous assignment, diff --git a/test_regress/t/t_param_store_bad.out b/test_regress/t/t_param_store_bad.out new file mode 100644 index 000000000..7a47a6e14 --- /dev/null +++ b/test_regress/t/t_param_store_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_param_store_bad.v:12:31: Storing to parameter variable 'S' in a context that is determed only at runtime + 12 | $value$plusargs("S=%s", S); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_param_store_bad.py b/test_regress/t/t_param_store_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_param_store_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_param_store_bad.v b/test_regress/t/t_param_store_bad.v new file mode 100644 index 000000000..5f617d9d7 --- /dev/null +++ b/test_regress/t/t_param_store_bad.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t #( + string S = "" + ); + + initial begin + $value$plusargs("S=%s", S); // BAD assignment to S + #1; // Original bug got compile time error only with this line + $display("S=%s", S); + $finish; + end + +endmodule From 753ea29df8ebf1666e720c1d9e8bb62fb694deb8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 5 Nov 2024 00:58:46 -0500 Subject: [PATCH 020/171] Add error on illegal enum base type (#3010). --- Changes | 3 ++- src/V3Width.cpp | 15 ++++++++------- test_regress/t/t_dist_warn_coverage.py | 1 - test_regress/t/t_enum_base_bad.out | 5 +++++ test_regress/t/t_enum_base_bad.py | 16 ++++++++++++++++ test_regress/t/t_enum_base_bad.v | 23 +++++++++++++++++++++++ 6 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 test_regress/t/t_enum_base_bad.out create mode 100755 test_regress/t/t_enum_base_bad.py create mode 100644 test_regress/t/t_enum_base_bad.v diff --git a/Changes b/Changes index 40b9b157e..de3482830 100644 --- a/Changes +++ b/Changes @@ -13,8 +13,9 @@ Verilator 5.031 devel **Minor:** -* Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] +* Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 1f7c25235..dbceb2b82 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2346,6 +2346,13 @@ class WidthVisitor final : public VNVisitor { UINFO(5, " ENUMDTYPE " << nodep << endl); nodep->refDTypep(iterateEditMoveDTypep(nodep, nodep->subDTypep())); nodep->dtypep(nodep); + AstBasicDType* basicp = nodep->dtypep()->skipRefp()->basicp(); + if (!basicp || !basicp->keyword().isIntNumeric()) { + nodep->v3error( + "Enum type must be an integer atom or vector type (IEEE 1800-2023 6.19)"); + basicp = nodep->findSigned32DType()->basicp(); + nodep->refDTypep(basicp); + } nodep->widthFromSub(nodep->subDTypep()); // Assign widths userIterateAndNext(nodep->itemsp(), WidthVP{nodep->dtypep(), BOTH}.p()); @@ -2376,17 +2383,11 @@ class WidthVisitor final : public VNVisitor { itemp->v3error("Enum value that is unassigned cannot follow value with X/Zs " "(IEEE 1800-2023 6.19)"); } - if (!nodep->dtypep()->basicp() - && !nodep->dtypep()->basicp()->keyword().isIntNumeric()) { - itemp->v3error("Enum names without values only allowed on numeric types"); - // as can't +1 to resolve them. - } itemp->valuep(new AstConst{itemp->fileline(), num}); } const AstConst* const constp = VN_AS(itemp->valuep(), Const); - if (constp->num().isFourState() && nodep->dtypep()->basicp() - && !nodep->dtypep()->basicp()->isFourstate()) { + if (constp->num().isFourState() && basicp->basicp() && !basicp->isFourstate()) { itemp->v3error("Enum value with X/Zs cannot be assigned to non-fourstate type " "(IEEE 1800-2023 6.19)"); } diff --git a/test_regress/t/t_dist_warn_coverage.py b/test_regress/t/t_dist_warn_coverage.py index 3ad81cedc..e953e0217 100755 --- a/test_regress/t/t_dist_warn_coverage.py +++ b/test_regress/t/t_dist_warn_coverage.py @@ -20,7 +20,6 @@ Suppressed = {} for s in [ ' exited with ', # Is hit; driver.py filters out 'EOF in unterminated string', # Instead get normal unterminated - 'Enum names without values only allowed on numeric types', # Hard to hit 'Enum ranges must be integral, per spec', # Hard to hit 'Import package not found: ', # Errors earlier, until future parser released 'Return with return value isn\'t underneath a function', # Hard to hit, get other bad return messages diff --git a/test_regress/t/t_enum_base_bad.out b/test_regress/t/t_enum_base_bad.out new file mode 100644 index 000000000..74839d10a --- /dev/null +++ b/test_regress/t/t_enum_base_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_enum_base_bad.v:13:12: Enum type must be an integer atom or vector type (IEEE 1800-2023 6.19) + : ... note: In instance 't' + 13 | typedef enum s_t { + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_enum_base_bad.py b/test_regress/t/t_enum_base_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_enum_base_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_enum_base_bad.v b/test_regress/t/t_enum_base_bad.v new file mode 100644 index 000000000..2647b47e8 --- /dev/null +++ b/test_regress/t/t_enum_base_bad.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + + typedef struct { + int a; + } s_t; + + typedef enum s_t { + EN_ZERO } bad_t; + + typedef int int_t; + + typedef enum int_t { EN_ONE = 1 } ok1_t; + + s_t s; + int_t i; + +endmodule From 87bd8fefa0e94e3563123d6a7832c30f3dac1b75 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 5 Nov 2024 01:22:56 -0500 Subject: [PATCH 021/171] Add error on `wait` with missing `.triggered`. (#4457) --- Changes | 1 + src/V3Width.cpp | 9 +++++++++ test_regress/t/t_wait_no_triggered_bad.out | 6 ++++++ test_regress/t/t_wait_no_triggered_bad.py | 16 ++++++++++++++++ test_regress/t/t_wait_no_triggered_bad.v | 21 +++++++++++++++++++++ 5 files changed, 53 insertions(+) create mode 100755 test_regress/t/t_wait_no_triggered_bad.out create mode 100755 test_regress/t/t_wait_no_triggered_bad.py create mode 100644 test_regress/t/t_wait_no_triggered_bad.v diff --git a/Changes b/Changes index de3482830..8043e2793 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,7 @@ Verilator 5.031 devel **Minor:** * Add error on illegal enum base type (#3010). [Iztok Jeras] +* Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index dbceb2b82..6d5621da4 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6131,6 +6131,15 @@ class WidthVisitor final : public VNVisitor { if (v3Global.opt.timing().isSetTrue()) { iterateCheckBool(nodep, "Wait", nodep->condp(), BOTH); // it's like an if() condition. + // TODO check also inside complex event expressions + if (AstNodeVarRef* const varrefp = VN_CAST(nodep->condp(), NodeVarRef)) { + if (varrefp->isEvent()) { + varrefp->v3error("Wait statement conditions do not take raw events" + " (IEEE 1800-2023 15.5.3)\n" + << varrefp->warnMore() << "... Suggest use '" + << varrefp->prettyName() << ".triggered'"); + } + } iterateNull(nodep->stmtsp()); return; } else if (v3Global.opt.timing().isSetFalse()) { diff --git a/test_regress/t/t_wait_no_triggered_bad.out b/test_regress/t/t_wait_no_triggered_bad.out new file mode 100755 index 000000000..2b4628408 --- /dev/null +++ b/test_regress/t/t_wait_no_triggered_bad.out @@ -0,0 +1,6 @@ +%Error: t/t_wait_no_triggered_bad.v:15:12: Wait statement conditions do not take raw events (IEEE 1800-2023 15.5.3) + : ... note: In instance 't' + : ... Suggest use 'e_my_event.triggered' + 15 | wait(e_my_event); + | ^~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_wait_no_triggered_bad.py b/test_regress/t/t_wait_no_triggered_bad.py new file mode 100755 index 000000000..5df24a780 --- /dev/null +++ b/test_regress/t/t_wait_no_triggered_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(verilator_flags2=['--timing'], fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_wait_no_triggered_bad.v b/test_regress/t/t_wait_no_triggered_bad.v new file mode 100644 index 000000000..0d827874d --- /dev/null +++ b/test_regress/t/t_wait_no_triggered_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + event e_my_event; + + initial begin + #(1us); + wait(e_my_event.triggered); // Ok + #(1us); + wait(e_my_event); // Bad + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From e47208d9b303c37e585a4a2a6719e6ade7c901cc Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Wed, 6 Nov 2024 23:31:48 +0100 Subject: [PATCH 022/171] Support queue's assignment `push_back/push_front('{})` (#5585) (#5586) Co-authored-by: Udaya Raj Subedi <075bei047.udaya@pcampus.edu.np> --- src/V3Width.cpp | 4 ++- test_regress/t/t_queue_assignment.py | 18 ++++++++++++ test_regress/t/t_queue_assignment.v | 41 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_queue_assignment.py create mode 100644 test_regress/t/t_queue_assignment.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 6d5621da4..87760c0bb 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3129,7 +3129,9 @@ class WidthVisitor final : public VNVisitor { // Any AstWith is checked later when know types, in methodWithArgument for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) { if (AstArg* const argp = VN_CAST(pinp, Arg)) { - if (argp->exprp()) userIterate(argp->exprp(), WidthVP{SELF, BOTH}.p()); + if (argp->exprp()) + userIterate(argp->exprp(), + WidthVP{nodep->fromp()->dtypep()->subDTypep(), BOTH}.p()); } } // Find the fromp dtype - should be a class diff --git a/test_regress/t/t_queue_assignment.py b/test_regress/t/t_queue_assignment.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_queue_assignment.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_queue_assignment.v b/test_regress/t/t_queue_assignment.v new file mode 100644 index 000000000..80f52ca52 --- /dev/null +++ b/test_regress/t/t_queue_assignment.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by PlanV GmbH. +// SPDX-License-Identifier: CC0-1.0 + +module t_queue_assignment; + typedef int T_QI[$]; + T_QI jagged_array[$]; // int jagged_array[$][$]; + initial begin + jagged_array = '{ {1}, T_QI'{2,3,4}, {5,6} }; + // jagged_array[0][0] = 1 -- jagged_array[0] is a queue of 1 int + // jagged_array[1][0] = 2 -- jagged_array[1] is a queue of 3 ints + // jagged_array[1][1] = 3 + // jagged_array[1][2] = 4 + // jagged_array[2][0] = 5 -- jagged_array[2] is a queue of 2 ints + // jagged_array[2][1] = 6 + jagged_array.push_back('{7}); + jagged_array.push_back('{8, 9, 10}); + jagged_array.push_front('{0, 1}); + print_and_check(); + + $write("*-* All Finished *-*\n"); + $finish; + end + + task automatic print_and_check(); + integer i, j; + int expected_values[][] = '{ '{0, 1}, '{1}, '{2, 3, 4}, '{5, 6}, '{7}, '{8, 9, 10} }; + + for (i = 0; i < jagged_array.size(); i++) begin + for (j = 0; j < jagged_array[i].size(); j++) begin + // $display("jagged_array[%0d][%0d] = %0d", i, j, jagged_array[i][j]); + if (jagged_array[i][j] !== expected_values[i][j]) begin + $stop; + end + end + end + endtask + +endmodule From 2e1128b417264d233efe2640939bc083115690e9 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 6 Nov 2024 19:21:03 -0500 Subject: [PATCH 023/171] Internals: Iterator cleanup. No functional change intended. --- src/V3Options.cpp | 23 +++++++++++------------ src/V3ParseImp.cpp | 4 ++-- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/V3Options.cpp b/src/V3Options.cpp index dee87bee0..ae32fdf3d 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -418,24 +418,23 @@ string V3Options::allArgsStringForHierBlock(bool forTop, bool forCMake) const { string out; bool stripArg = false; bool stripArgIfNum = false; - for (std::list::const_iterator it = m_impp->m_lineArgs.begin(); - it != m_impp->m_lineArgs.end(); ++it) { + for (const string& arg : m_impp->m_lineArgs) { if (stripArg) { stripArg = false; continue; } if (stripArgIfNum) { stripArgIfNum = false; - if (isdigit((*it)[0])) continue; + if (isdigit(arg[0])) continue; } int skip = 0; - if (it->length() >= 2 && (*it)[0] == '-' && (*it)[1] == '-') { + if (arg.length() >= 2 && arg[0] == '-' && arg[1] == '-') { skip = 2; - } else if (it->length() >= 1 && (*it)[0] == '-') { + } else if (arg.length() >= 1 && arg[0] == '-') { skip = 1; } - if (skip > 0) { // *it is an option - const string opt = it->substr(skip); // Remove '-' in the beginning + if (skip > 0) { // arg is an option + const string opt = arg.substr(skip); // Remove '-' in the beginning const int numStrip = stripOptionsForChildRun(opt, forTop); if (numStrip) { UASSERT(0 <= numStrip && numStrip <= 3, "should be one of 0, 1, 2, 3"); @@ -444,15 +443,15 @@ string V3Options::allArgsStringForHierBlock(bool forTop, bool forCMake) const { continue; } } else { // Not an option - if ((forCMake && vFiles.find(*it) != vFiles.end()) // Remove HDL - || m_cppFiles.find(*it) != m_cppFiles.end()) { // Remove C++ + if ((forCMake && vFiles.find(arg) != vFiles.end()) // Remove HDL + || m_cppFiles.find(arg) != m_cppFiles.end()) { // Remove C++ continue; } } if (out != "") out += " "; - // Don't use opt here because '-' is removed in it - // Use double quote because *it may contain whitespaces - out += '"' + VString::quoteAny(*it, '"', '\\') + '"'; + // Don't use opt here because '-' is removed in arg + // Use double quote because arg may contain whitespaces + out += '"' + VString::quoteAny(arg, '"', '\\') + '"'; } return out; } diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 1a8076be4..df44d53a5 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -271,8 +271,8 @@ void V3ParseImp::preprocDumps(std::ostream& os, bool forInputs) { for (auto& buf : m_ppBuffers) { if (noblanks) { bool blank = true; - for (string::iterator its = buf.begin(); its != buf.end(); ++its) { - if (!std::isspace(*its) && *its != '\n') { + for (const char ch : buf) { + if (!std::isspace(ch) && ch != '\n') { blank = false; break; } From 6083480abbc9e8d5888822f072cf3e7bd73e3cf0 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 8 Nov 2024 12:53:43 +0100 Subject: [PATCH 024/171] Fix `rand` dynamic arrays with null handles (#5594) l --- src/V3Randomize.cpp | 5 ++++- test_regress/t/t_randomize_array.v | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index c248c112e..dfece340b 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1471,9 +1471,12 @@ class RandomizeVisitor final : public VNVisitor { AstMethodCall* const callp = new AstMethodCall{fl, exprp, "randomize", nullptr}; callp->taskp(memberFuncp); callp->dtypeFrom(memberFuncp); - return new AstAssign{ + AstAssign* const assignp = new AstAssign{ fl, new AstVarRef{fl, outputVarp, VAccess::WRITE}, new AstAnd{fl, new AstVarRef{fl, outputVarp, VAccess::READ}, callp}}; + return new AstIf{ + fl, new AstNeq{fl, exprp->cloneTree(false), new AstConst{fl, AstConst::Null{}}}, + assignp}; } else if (AstDynArrayDType* const dynarrayDtp = VN_CAST(memberDtp, DynArrayDType)) { return createArrayForeachLoop(fl, dynarrayDtp, exprp, outputVarp); } else if (AstQueueDType* const queueDtp = VN_CAST(memberDtp, QueueDType)) { diff --git a/test_regress/t/t_randomize_array.v b/test_regress/t/t_randomize_array.v index 63747653c..f1a5abece 100755 --- a/test_regress/t/t_randomize_array.v +++ b/test_regress/t/t_randomize_array.v @@ -72,6 +72,7 @@ class unconstrained_dynamic_array_test; rand int dynamic_array_1d[]; rand int dynamic_array_2d[][]; rand Cls class_dynamic_array[]; + rand Cls class_dynamic_array_null[]; function new(); // Initialize 1D dynamic array @@ -94,6 +95,8 @@ class unconstrained_dynamic_array_test; class_dynamic_array[i] = new; end + class_dynamic_array_null = new[2]; + endfunction function void check_randomization(); @@ -108,6 +111,9 @@ class unconstrained_dynamic_array_test; foreach (class_dynamic_array[i]) begin `check_rand(this, class_dynamic_array[i].x) end + foreach (class_dynamic_array_null[i]) begin + if (class_dynamic_array_null[i] != null) $stop; + end endfunction endclass From 61d2284eab7ba6ca6715d4d371c66a7c52f6403a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 8 Nov 2024 07:47:46 -0500 Subject: [PATCH 025/171] Commentary --- src/verilog.y | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 0272e2c4d..d7058a9bc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2348,7 +2348,7 @@ tf_variable_identifier: // IEEE: part of list_of_tf_variable_ide variable_declExpr: // IEEE: part of variable_decl_assignment - rhs of expr expr { $$ = $1; } | dynamic_array_new { $$ = $1; } - | class_new { $$ = $1; } + | class_newNoScope { $$ = $1; } ; variable_dimensionListE: // IEEE: variable_dimension + empty @@ -3609,7 +3609,7 @@ statement_item: // IEEE: statement_item // // IEEE: blocking_assignment // // 1800-2009 restricts LHS of assignment to new to not have a range // // This is ignored to avoid conflicts - | fexprLvalue '=' class_new ';' { $$ = new AstAssign{$2, $1, $3}; } + | fexprLvalue '=' class_newNoScope ';' { $$ = new AstAssign{$2, $1, $3}; } | fexprLvalue '=' dynamic_array_new ';' { $$ = new AstAssign{$2, $1, $3}; } // // IEEE: inc_or_dec_expression | finc_or_dec_expression ';' { $$ = $1; } @@ -3858,8 +3858,8 @@ pinc_or_dec_expression: // IEEE: inc_or_dec_expression (for property //UNSUP BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g}) // {copied} //UNSUP ; -class_new: // ==IEEE: class_new - // // Special precence so (...) doesn't match expr +class_newNoScope: // IEEE: class_new but no packageClassScope (issue #4199) + // // Special precedence so (...) doesn't match expr yNEW__ETC { $$ = new AstNew{$1, nullptr}; } | yNEW__ETC expr { $$ = new AstNewCopy{$1, $2}; } | yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew{$1, $3}; } @@ -4137,14 +4137,14 @@ funcRef: // IEEE: part of tf_call task_subroutine_callNoSemi: // similar to IEEE task_subroutine_call but without ';' // // Expr included here to resolve our not knowing what is a method call // // Expr here must result in a subroutine_call - task_subroutine_callNoMethod { $$ = $1->makeStmt(); } + task_subroutine_callNoMethod { $$ = $1->makeStmt(); } | fexpr '.' task_subroutine_callNoMethod { $$ = (new AstDot{$2, false, $1, $3})->makeStmt(); } - | system_t_call { $$ = $1; } + | system_t_call { $$ = $1; } // // Not here in IEEE; from class_constructor_declaration // // Because we've joined class_constructor_declaration into generic functions // // Way over-permissive; // // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ] - | fexpr '.' class_new { $$ = (new AstDot{$2, false, $1, $3})->makeStmt(); } + | fexpr '.' class_newNoScope { $$ = (new AstDot{$2, false, $1, $3})->makeStmt(); } ; task_subroutine_callNoMethod: // function_subroutine_callNoMethod (as task) From a173883b2d3a3676aa38a27017c4d01803b1c92c Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Fri, 8 Nov 2024 20:04:58 +0100 Subject: [PATCH 026/171] Support basic constrained random for multi-dimensional dynamic array and queue (#5591) --- include/verilated_random.cpp | 81 +++--- include/verilated_random.h | 255 ++++++++++++------ src/V3Randomize.cpp | 10 +- .../t/t_constraint_dyn_queue_basic.py | 21 ++ test_regress/t/t_constraint_dyn_queue_basic.v | 113 ++++++++ 5 files changed, 350 insertions(+), 130 deletions(-) create mode 100755 test_regress/t/t_constraint_dyn_queue_basic.py create mode 100755 test_regress/t/t_constraint_dyn_queue_basic.v diff --git a/include/verilated_random.cpp b/include/verilated_random.cpp index 324e6cdbe..13c6a058a 100644 --- a/include/verilated_random.cpp +++ b/include/verilated_random.cpp @@ -22,6 +22,7 @@ #include "verilated_random.h" +#include #include #include #include @@ -281,37 +282,6 @@ std::string parseNestedSelect(const std::string& nested_select_expr, indices.push_back(idx); return name; } - -std::string flattenIndices(const std::vector& indices, const VlRandomVar* const var) { - int flattenedIndex = 0; - int multiplier = 1; - for (int i = indices.size() - 1; i >= 0; --i) { - int indexValue = 0; - std::string trimmedIndex = indices[i]; - - trimmedIndex.erase(0, trimmedIndex.find_first_not_of(" \t")); - trimmedIndex.erase(trimmedIndex.find_last_not_of(" \t") + 1); - - if (trimmedIndex.find("#x") == 0) { - indexValue = std::strtoul(trimmedIndex.substr(2).c_str(), nullptr, 16); - } else if (trimmedIndex.find("#b") == 0) { - indexValue = std::strtoul(trimmedIndex.substr(2).c_str(), nullptr, 2); - } else { - indexValue = std::strtoul(trimmedIndex.c_str(), nullptr, 10); - } - const int length = var->getLength(i); - if (length == -1) { - VL_WARN_MT(__FILE__, __LINE__, "randomize", - "Internal: Wrong Call: Only RandomArray can call getLength()"); - break; - } - flattenedIndex += indexValue * multiplier; - multiplier *= length; - } - std::string hexString = std::to_string(flattenedIndex); - while (hexString.size() < 8) { hexString.insert(0, "0"); } - return "#x" + hexString; -} //====================================================================== // VlRandomizer:: Methods @@ -404,7 +374,11 @@ bool VlRandomizer::next(VlRNG& rngr) { f << "(define-fun __Vbv ((b Bool)) (_ BitVec 1) (ite b #b1 #b0))\n"; f << "(define-fun __Vbool ((v (_ BitVec 1))) Bool (= #b1 v))\n"; for (const auto& var : m_vars) { - f << "(declare-fun " << var.second->name() << " () "; + if (var.second->dimension() > 0) { + auto arrVarsp = std::make_shared(m_arr_vars); + var.second->setArrayInfo(arrVarsp); + } + f << "(declare-fun " << var.first << " () "; var.second->emitType(f); f << ")\n"; } @@ -444,9 +418,14 @@ bool VlRandomizer::parseSolution(std::iostream& f) { } f << "(get-value ("; - for (const auto& var : m_vars) var.second->emitGetValue(f); + for (const auto& var : m_vars) { + if (var.second->dimension() > 0) { + auto arrVarsp = std::make_shared(m_arr_vars); + var.second->setArrayInfo(arrVarsp); + } + var.second->emitGetValue(f); + } f << "))\n"; - // Quasi-parse S-expression of the form ((x #xVALUE) (y #bVALUE) (z #xVALUE)) char c; f >> c; @@ -455,7 +434,6 @@ bool VlRandomizer::parseSolution(std::iostream& f) { "Internal: Unable to parse solver's response: invalid S-expression"); return false; } - while (true) { f >> c; if (c == ')') break; @@ -471,7 +449,6 @@ bool VlRandomizer::parseSolution(std::iostream& f) { if (name == "(select") { const std::string selectExpr = readUntilBalanced(f); name = parseNestedSelect(selectExpr, indices); - idx = indices[0]; } std::getline(f, value, ')'); const auto it = m_vars.find(name); @@ -480,12 +457,34 @@ bool VlRandomizer::parseSolution(std::iostream& f) { if (m_randmode && !varr.randModeIdxNone()) { if (!(m_randmode->at(varr.randModeIdx()))) continue; } - if (indices.size() > 1) { - const std::string flattenedIndex = flattenIndices(indices, &varr); - varr.set(flattenedIndex, value); - } else { - varr.set(idx, value); + if (!indices.empty()) { + std::ostringstream oss; + oss << varr.name(); + for (const auto& hex_index : indices) { + const size_t start = hex_index.find_first_not_of(" "); + if (start == std::string::npos || hex_index.substr(start, 2) != "#x") { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", + "Error: hex_index contains invalid format"); + continue; + } + const int index = std::stoi(hex_index.substr(start + 2), nullptr, 16); + oss << "[" << index << "]"; + } + const std::string indexed_name = oss.str(); + const auto it = std::find_if(m_arr_vars.begin(), m_arr_vars.end(), + [&indexed_name](const auto& entry) { + return entry.second->m_name == indexed_name; + }); + if (it != m_arr_vars.end()) { + std::ostringstream ss; + ss << "#x" << std::hex << std::setw(8) << std::setfill('0') << it->second->m_index; + idx = ss.str(); + } else { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", + "Error: indexed_name not found in m_arr_vars"); + } } + varr.set(idx, value); } return true; } diff --git a/include/verilated_random.h b/include/verilated_random.h index 2ae2dcb22..d679f3e0e 100644 --- a/include/verilated_random.h +++ b/include/verilated_random.h @@ -27,10 +27,25 @@ #include "verilated.h" +#include #include - //============================================================================= // VlRandomExpr and subclasses represent expressions for the constraint solver. +class ArrayInfo final { +public: + const std::string + m_name; // Name of the array variable, including index notation (e.g., arr[2][1]) + void* const m_datap; // Reference to the array variable data + const int m_index; // Flattened (1D) index of the array element + const std::vector m_indices; // Multi-dimensional indices of the array element + + ArrayInfo(const std::string& name, void* datap, int index, const std::vector& indices) + : m_name(name) + , m_datap(datap) + , m_index(index) + , m_indices(indices) {} +}; +using ArrayInfoMap = std::map>; class VlRandomVar VL_NOT_FINAL { const char* const m_name; // Variable name @@ -58,7 +73,22 @@ public: virtual void emitExtract(std::ostream& s, int i) const; virtual void emitType(std::ostream& s) const; virtual int totalWidth() const; - virtual int getLength(int dimension) const { return -1; } + mutable std::shared_ptr m_arrVarsRefp; + void setArrayInfo(const std::shared_ptr& arrVarsRefp) const { + m_arrVarsRefp = arrVarsRefp; + } + mutable std::map count_cache; + int countMatchingElements(const ArrayInfoMap& arr_vars, const std::string& base_name) const { + if (VL_LIKELY(count_cache.find(base_name) != count_cache.end())) + return count_cache[base_name]; + int count = 0; + for (int index = 0; arr_vars.find(base_name + std::to_string(index)) != arr_vars.end(); + ++index) { + ++count; + } + count_cache[base_name] = count; + return count; + } }; template @@ -68,52 +98,12 @@ public: std::uint32_t randModeIdx) : VlRandomVar{name, width, datap, dimension, randModeIdx} {} void* datap(int idx) const override { + const std::string indexed_name = name() + std::to_string(idx); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) return it->second->m_datap; return &static_cast(VlRandomVar::datap(idx))->atWrite(idx); } - void emitSelect(std::ostream& s, int i) const { - s << " (select " << name() << " #x"; - for (int j = 28; j >= 0; j -= 4) s << "0123456789abcdef"[(i >> j) & 0xf]; - s << ')'; - } - void emitGetValue(std::ostream& s) const override { - const int length = static_cast(VlRandomVar::datap(0))->size(); - for (int i = 0; i < length; i++) emitSelect(s, i); - } - void emitType(std::ostream& s) const override { - s << "(Array (_ BitVec 32) (_ BitVec " << width() << "))"; - } - int totalWidth() const override { - const int length = static_cast(VlRandomVar::datap(0))->size(); - return width() * length; - } - void emitExtract(std::ostream& s, int i) const override { - const int j = i / width(); - i = i % width(); - s << " ((_ extract " << i << ' ' << i << ')'; - emitSelect(s, j); - s << ')'; - } -}; - -template -class VlRandomArrayVar final : public VlRandomVar { -public: - VlRandomArrayVar(const char* name, int width, void* datap, int dimension, - std::uint32_t randModeIdx) - : VlRandomVar{name, width, datap, dimension, randModeIdx} {} - - void* datap(int idx) const override { - if (idx < 0) return &static_cast(VlRandomVar::datap(0))->operator[](0); - std::vector indices(dimension()); - for (int dim = dimension() - 1; dim >= 0; --dim) { - const int length = getLength(dim); - indices[dim] = idx % length; - idx /= length; - } - return &static_cast(VlRandomVar::datap(0))->find_element(indices); - } - - void emitSelect(std::ostream& s, const std::vector& indices) const { + void emitSelect(std::ostream& s, const std::vector& indices) const { for (size_t idx = 0; idx < indices.size(); ++idx) s << "(select "; s << name(); for (size_t idx = 0; idx < indices.size(); ++idx) { @@ -124,33 +114,17 @@ public: s << ")"; } } - - int getLength(int dimension) const override { - const auto var = static_cast(datap(-1)); - const int lenth = var->find_length(dimension); - return lenth; - } - void emitGetValue(std::ostream& s) const override { - const int total_dimensions = dimension(); - std::vector lengths; - for (int dim = 0; dim < total_dimensions; dim++) { - const int len = getLength(dim); - lengths.push_back(len); - } - std::vector indices(total_dimensions, 0); - while (true) { - emitSelect(s, indices); - int currentDimension = total_dimensions - 1; - while (currentDimension >= 0 - && ++indices[currentDimension] >= lengths[currentDimension]) { - indices[currentDimension] = 0; - --currentDimension; + const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); + for (int i = 0; i < elementCounts; i++) { + const std::string indexed_name = name() + std::to_string(i); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) { + const std::vector& indices = it->second->m_indices; + emitSelect(s, indices); } - if (currentDimension < 0) break; } } - void emitType(std::ostream& s) const override { if (dimension() > 0) { for (int i = 0; i < dimension(); ++i) s << "(Array (_ BitVec 32) "; @@ -158,29 +132,79 @@ public: for (int i = 0; i < dimension(); ++i) s << ")"; } } - int totalWidth() const override { - int totalLength = 1; - for (int dim = 0; dim < dimension(); ++dim) { - const int length = getLength(dim); - if (length == -1) return 0; - totalLength *= length; - } - return width() * totalLength; + const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); + return width() * elementCounts; } - void emitExtract(std::ostream& s, int i) const override { const int j = i / width(); i = i % width(); - std::vector indices(dimension()); - int idx = j; - for (int dim = dimension() - 1; dim >= 0; --dim) { - int length = getLength(dim); - indices[dim] = idx % length; - idx /= length; - } s << " ((_ extract " << i << ' ' << i << ')'; - emitSelect(s, indices); + const std::string indexed_name = name() + std::to_string(j); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) { + const std::vector& indices = it->second->m_indices; + emitSelect(s, indices); + } + s << ')'; + } +}; + +template +class VlRandomArrayVar final : public VlRandomVar { +public: + VlRandomArrayVar(const char* name, int width, void* datap, int dimension, + std::uint32_t randModeIdx) + : VlRandomVar{name, width, datap, dimension, randModeIdx} {} + void* datap(int idx) const override { + const std::string indexed_name = name() + std::to_string(idx); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) return it->second->m_datap; + return &static_cast(VlRandomVar::datap(idx))->operator[](idx); + } + void emitSelect(std::ostream& s, const std::vector& indices) const { + for (size_t idx = 0; idx < indices.size(); ++idx) s << "(select "; + s << name(); + for (size_t idx = 0; idx < indices.size(); ++idx) { + s << " #x"; + for (int j = 28; j >= 0; j -= 4) { + s << "0123456789abcdef"[(indices[idx] >> j) & 0xf]; + } + s << ")"; + } + } + void emitGetValue(std::ostream& s) const override { + const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); + for (int i = 0; i < elementCounts; i++) { + const std::string indexed_name = name() + std::to_string(i); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) { + const std::vector& indices = it->second->m_indices; + emitSelect(s, indices); + } + } + } + void emitType(std::ostream& s) const override { + if (dimension() > 0) { + for (int i = 0; i < dimension(); ++i) s << "(Array (_ BitVec 32) "; + s << "(_ BitVec " << width() << ")"; + for (int i = 0; i < dimension(); ++i) s << ")"; + } + } + int totalWidth() const override { + const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); + return width() * elementCounts; + } + void emitExtract(std::ostream& s, int i) const override { + const int j = i / width(); + i = i % width(); + s << " ((_ extract " << i << ' ' << i << ')'; + const std::string indexed_name = name() + std::to_string(j); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) { + const std::vector& indices = it->second->m_indices; + emitSelect(s, indices); + } s << ')'; } }; @@ -192,6 +216,7 @@ class VlRandomizer final { std::vector m_constraints; // Solver-dependent constraints std::map> m_vars; // Solver-dependent // variables + ArrayInfoMap m_arr_vars; // Tracks each element in array structures for iteration const VlQueue* m_randmode; // rand_mode state; // PRIVATE METHODS @@ -220,6 +245,10 @@ public: if (m_vars.find(name) != m_vars.end()) return; m_vars[name] = std::make_shared>>( name, width, &var, dimension, randmodeIdx); + if (dimension > 0) { + idx = 0; + record_arr_table(var, name, dimension, {}); + } } template void write_var(VlUnpacked& var, int width, const char* name, int dimension, @@ -227,6 +256,60 @@ public: if (m_vars.find(name) != m_vars.end()) return; m_vars[name] = std::make_shared>>( name, width, &var, dimension, randmodeIdx); + if (dimension > 0) { + idx = 0; + record_arr_table(var, name, dimension, {}); + } + } + int idx = 0; + std::string generateKey(const std::string& name, int idx) { + if (!name.empty() && name[0] == '\\') { + const size_t space_pos = name.find(' '); + return (space_pos != std::string::npos ? name.substr(0, space_pos) : name) + + std::to_string(idx); + } + const size_t bracket_pos = name.find('['); + return (bracket_pos != std::string::npos ? name.substr(0, bracket_pos) : name) + + std::to_string(idx); + } + template + void record_arr_table(T& var, const std::string name, int dimension, + std::vector indices) { + const std::string key = generateKey(name, idx); + m_arr_vars[key] = std::make_shared(name, &var, idx, indices); + idx += 1; + } + template + void record_arr_table(VlQueue& var, const std::string name, int dimension, + std::vector indices) { + if ((dimension > 0) && (var.size() != 0)) { + for (size_t i = 0; i < var.size(); ++i) { + const std::string indexed_name = name + "[" + std::to_string(i) + "]"; + indices.push_back(i); + record_arr_table(var.atWrite(i), indexed_name, dimension - 1, indices); + indices.pop_back(); + } + } else { + const std::string key = generateKey(name, idx); + m_arr_vars[key] = std::make_shared(name, &var, idx, indices); + ++idx; + } + } + template + void record_arr_table(VlUnpacked& var, const std::string name, int dimension, + std::vector indices) { + if ((dimension > 0) && (N != 0)) { + for (size_t i = 0; i < N; ++i) { + const std::string indexed_name = name + "[" + std::to_string(i) + "]"; + indices.push_back(i); + record_arr_table(var.operator[](i), indexed_name, dimension - 1, indices); + indices.pop_back(); + } + } else { + const std::string key = generateKey(name, idx); + m_arr_vars[key] = std::make_shared(name, &var, idx, indices); + idx += 1; + } } void hard(std::string&& constraint); void clear(); diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index dfece340b..24a5a41bb 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -618,7 +618,8 @@ class ConstraintExprVisitor final : public VNVisitor { VAccess::READWRITE}, "write_var"}; uint32_t dimension = 0; - if (VN_IS(varp->dtypep(), UnpackArrayDType)) { + if (VN_IS(varp->dtypep(), UnpackArrayDType) || VN_IS(varp->dtypep(), DynArrayDType) + || VN_IS(varp->dtypep(), QueueDType)) { const std::pair dims = varp->dtypep()->dimensions(/*includeBasic=*/true); const uint32_t unpackedDimensions = dims.second; @@ -631,8 +632,11 @@ class ConstraintExprVisitor final : public VNVisitor { varRefp->classOrPackagep(classOrPackagep); methodp->addPinsp(varRefp); size_t width = varp->width(); - if (VN_IS(varp->dtypep(), DynArrayDType) || VN_IS(varp->dtypep(), QueueDType)) - width = varp->dtypep()->subDTypep()->width(); + AstNodeDType* tmpDtypep = varp->dtypep(); + while (VN_IS(tmpDtypep, UnpackArrayDType) || VN_IS(tmpDtypep, DynArrayDType) + || VN_IS(tmpDtypep, QueueDType)) + tmpDtypep = tmpDtypep->subDTypep(); + width = tmpDtypep->width(); methodp->addPinsp( new AstConst{varp->dtypep()->fileline(), AstConst::Unsized64{}, width}); AstNodeExpr* const varnamep diff --git a/test_regress/t/t_constraint_dyn_queue_basic.py b/test_regress/t/t_constraint_dyn_queue_basic.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_constraint_dyn_queue_basic.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_dyn_queue_basic.v b/test_regress/t/t_constraint_dyn_queue_basic.v new file mode 100755 index 000000000..f115be10c --- /dev/null +++ b/test_regress/t/t_constraint_dyn_queue_basic.v @@ -0,0 +1,113 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by PlanV GmbH. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +class ConstrainedDynamicQueueArray; + rand int queue_1d[$]; + rand int queue[$][$]; + rand int dyn[][]; + rand int queue_dyn[$][]; + rand int dyn_queue[][$]; + rand int queue_unp[$][3]; + rand int unp_queue[3][$]; + rand int \array_w[ith_es]cape [3][2]; + + // Constraints for the queues and dynamic arrays + constraint queue_constraints { + foreach (queue_1d[i]) queue_1d[i] == i + 2; + foreach (queue[i, j]) queue[i][j] == (2 * i) + j; + } + + constraint dyn_constraints { + dyn[0][0] == 10; + dyn[1][0] inside {20, 30, 40}; + dyn[1][1] > 50; + dyn[0][1] < 100; + dyn[0][2] inside {5, 15, 25}; + } + + constraint queue_dyn_constraints { + foreach (queue_dyn[i, j]) queue_dyn[i][j] == i + j + 3; + } + + constraint dyn_queue_constraints { + foreach (dyn_queue[i, j]) dyn_queue[i][j] == (3 * i) + j + 2; + } + + constraint unp_queue_constraints { + foreach (unp_queue[i, j]) unp_queue[i][j] == (i * 5) + j + 1; + } + + constraint array_with_escape_constraints { + \array_w[ith_es]cape [0][0] == 6; + } + + // Constructor + function new(); + queue_1d = {1, 2, 3, 4}; + queue = '{ '{1, 2}, '{3, 4, 5}, '{6}}; + dyn = new[2]; + dyn[0] = new[3]; + dyn[1] = new[4]; + + queue_dyn = {}; + queue_dyn[0] = new[3]; + queue_dyn[1] = new[4]; + + dyn_queue = new[2]; + dyn_queue[0] = {7, 8, 9}; + dyn_queue[1] = {10}; + + queue_unp = {}; + + unp_queue[0] = {17, 18}; + unp_queue[1] = {19}; + unp_queue[2] = {20}; + endfunction + + // Self-check function + function void check(); + foreach (queue_1d[i]) `checkh(queue_1d[i], i + 2) + + foreach (queue[i, j]) `checkh(queue[i][j], (2 * i) + j) + + `checkh(dyn[0][0], 10) + `checkh(dyn[1][0] inside {20, 30, 40}, 1'b1) + `checkh(dyn[1][1] > 50, 1'b1) + `checkh(dyn[0][1] < 100, 1'b1) + `checkh(dyn[0][2] inside {5, 15, 25}, 1'b1) + + foreach (queue_dyn[i, j]) `checkh(queue_dyn[i][j], i + j + 3) + + foreach (dyn_queue[i, j]) `checkh(dyn_queue[i][j], (3 * i) + j + 2) + + `checkh(unp_queue[0][0], (0 * 5) + 0 + 1) + `checkh(unp_queue[0][1], (0 * 5) + 1 + 1) + `checkh(unp_queue[1][0], (1 * 5) + 0 + 1) + `checkh(unp_queue[2][0], (2 * 5) + 0 + 1) + + `checkh(\array_w[ith_es]cape [0][0], 6) + endfunction +endclass + +module t_constraint_dyn_queue_basic; + ConstrainedDynamicQueueArray array_test; + int success; + initial begin + $display("Test: Randomization for dynamic and mixed queues and arrays:"); + array_test = new(); + repeat(2) begin + success = array_test.randomize(); + `checkh(success, 1) + array_test.check(); + end + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From a55daf536755d0460ca36771b82de90aadceacc0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 07:56:47 -0500 Subject: [PATCH 027/171] Commentary --- README.rst | 2 -- test_regress/t/t_uvm_pkg_todo.vh | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 1a8f34017..5d4767137 100644 --- a/README.rst +++ b/README.rst @@ -15,8 +15,6 @@ :target: https://hub.docker.com/r/verilator/verilator .. |badge6| image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f :target: https://www.codacy.com/gh/verilator/verilator -.. |badge7| image:: https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg - :target: https://codecov.io/gh/verilator/verilator .. |badge8| image:: https://github.com/verilator/verilator/workflows/build/badge.svg :target: https://github.com/verilator/verilator/actions?query=workflow%3Abuild diff --git a/test_regress/t/t_uvm_pkg_todo.vh b/test_regress/t/t_uvm_pkg_todo.vh index 888258fa2..0ef277ddb 100644 --- a/test_regress/t/t_uvm_pkg_todo.vh +++ b/test_regress/t/t_uvm_pkg_todo.vh @@ -22444,8 +22444,8 @@ class uvm_reg_item extends uvm_sequence_item; uvm_elem_kind_e element_kind; uvm_object element; rand uvm_access_e kind; - //TODO issue-4625 - Rand fields of dynamic array types - //TODO %Error-UNSUPPORTED: t/t_uvm_pkg_todo.vh:21081:35: Unsupported: random member variable with type 'bit[]' + //TODO issue-5582 - Rand constraint with .size + //TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state /*rand*/ uvm_reg_data_t value[]; constraint max_values { value.size() > 0 && value.size() < 1000; } rand uvm_reg_addr_t offset; @@ -26866,8 +26866,8 @@ class uvm_reg_fifo extends uvm_reg; local uvm_reg_field value; local int m_set_cnt; local int unsigned m_size; - //TODO issue-4625 - Rand fields of dynamic array types - //TODO %Error-UNSUPPORTED: t/t_uvm_pkg_todo.vh:21081:35: Unsupported: random member variable with type 'bit[$]' + //TODO issue-5582 - Rand constraint with .size + //TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state /*rand*/ uvm_reg_data_t fifo[$]; constraint valid_fifo_size { fifo.size() <= m_size; From e55ed8eb6698bf4967f1c0f5c3e973f7bb31ccc7 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 08:24:50 -0500 Subject: [PATCH 028/171] Commentary --- src/V3Dead.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index f2657d703..a957da964 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -540,7 +540,7 @@ public: void V3Dead::deadifyModules(AstNetlist* nodep) { UINFO(2, __FUNCTION__ << ": " << endl); - { + { // node, elimUserVars, elimDTypes, elimScopes, elimCells, elimTopIfaces DeadVisitor{nodep, false, false, false, false, !v3Global.opt.topIfacesSupported()}; } // Destruct before checking V3Global::dumpCheckGlobalTree("deadModules", 0, dumpTreeEitherLevel() >= 6); From 3438d8f2b06f69d48834d94d97810cb5e260b170 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 08:34:17 -0500 Subject: [PATCH 029/171] Tests: Use illegal struct --- test_regress/t/t_struct_contents_bad.v | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_regress/t/t_struct_contents_bad.v b/test_regress/t/t_struct_contents_bad.v index e0981add9..b31734a07 100644 --- a/test_regress/t/t_struct_contents_bad.v +++ b/test_regress/t/t_struct_contents_bad.v @@ -30,6 +30,8 @@ endclass Cls c; // BAd } illegal_t; + illegal_t s; + initial begin $stop; end From 138daaf5650a02e3538986241166ae44c3fd2769 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 08:35:40 -0500 Subject: [PATCH 030/171] Commentary: Changes update --- Changes | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Changes b/Changes index 8043e2793..de90148a5 100644 --- a/Changes +++ b/Changes @@ -13,6 +13,8 @@ Verilator 5.031 devel **Minor:** +* Support queue's assignment `push_back/push_front('{})` (#5585) (#5586). [Yilou Wang] +* Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] @@ -23,6 +25,8 @@ Verilator 5.031 devel * Fix --output-groups leftover files issue (#5574). [Todd Strader] * Fix slow unsized number parsing (#5577). [Geza Lore] * Fix negative assignment pattern keys (#5580). [Iztok Jeras] +* Fix duplicate scope identifiers decoding (#5584). [Bartłomiej Chmiel, Antmicro Ltd.] +* Fix `rand` dynamic arrays with null handles (#5594). [Ryszard Rozak, Antmicro Ltd.] Verilator 5.030 2024-10-27 From 1e546bb9d9ec28be49d837fcf55c4cd64445f5ab Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 09:28:40 -0500 Subject: [PATCH 031/171] Add assertion on firing event inside class (#5597) --- src/V3Delayed.cpp | 1 + test_regress/t/t_event_class_fire.out | 5 +++++ test_regress/t/t_event_class_fire.py | 21 +++++++++++++++++++++ test_regress/t/t_event_class_fire.v | 24 ++++++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 test_regress/t/t_event_class_fire.out create mode 100755 test_regress/t/t_event_class_fire.py create mode 100644 test_regress/t/t_event_class_fire.v diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 5edee1370..4d43665ec 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -891,6 +891,7 @@ class DelayedVisitor final : public VNVisitor { ifp->addThensp(newp); } + UASSERT_OBJ(m_activep, nodep, "No active to handle FireEvent"); AstActive* const activep = new AstActive{flp, "nba-event", m_activep->sensesp()}; m_activep->addNextHere(activep); activep->addStmtsp(prep); diff --git a/test_regress/t/t_event_class_fire.out b/test_regress/t/t_event_class_fire.out new file mode 100644 index 000000000..5cd5a3d51 --- /dev/null +++ b/test_regress/t/t_event_class_fire.out @@ -0,0 +1,5 @@ +%Error: Internal Error: t/t_event_class_fire.v:10:7: ../V3Delayed.cpp:#: No active to handle FireEvent + : ... note: In instance '$unit::Cls' + 10 | ->> e; + | ^~~ + ... See the manual at https://verilator.org/verilator_doc.html for more assistance. diff --git a/test_regress/t/t_event_class_fire.py b/test_regress/t/t_event_class_fire.py new file mode 100755 index 000000000..9de681711 --- /dev/null +++ b/test_regress/t/t_event_class_fire.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +# Issue #5597 makes this fail +test.compile(fails=test.vlt_all, + expect_filename=test.golden_filename, + verilator_flags2=['--timing']) + +#test.execute() + +test.passes() diff --git a/test_regress/t/t_event_class_fire.v b/test_regress/t/t_event_class_fire.v new file mode 100644 index 000000000..325fbafc0 --- /dev/null +++ b/test_regress/t/t_event_class_fire.v @@ -0,0 +1,24 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls; + event e; + task trig_e(); + ->> e; + endtask +endclass + +module top(); + event e; + initial begin + Cls c; + c = new; + c.trig_e(); + wait(e.triggered); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 3fae11595a7653573b60dff324e43c66d9ef1e94 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 12:05:26 -0500 Subject: [PATCH 032/171] Support `pure constraint`. --- Changes | 1 + src/V3AstNodeOther.h | 7 ++++- src/V3AstNodes.cpp | 11 +++++++- src/V3LinkDot.cpp | 23 ++++++++++++++-- src/V3WidthCommit.cpp | 12 +++++++++ src/verilog.y | 3 +-- test_regress/t/t_constraint_pure.py | 21 +++++++++++++++ test_regress/t/t_constraint_pure.v | 26 +++++++++++++++++++ .../t/t_constraint_pure_missing_bad.out | 7 +++++ .../t/t_constraint_pure_missing_bad.py | 16 ++++++++++++ .../t/t_constraint_pure_missing_bad.v | 16 ++++++++++++ .../t/t_constraint_pure_nonabs_bad.out | 5 ++++ .../t/t_constraint_pure_nonabs_bad.py | 16 ++++++++++++ test_regress/t/t_constraint_pure_nonabs_bad.v | 12 +++++++++ test_regress/t/t_randomize_extern.out | 5 +--- 15 files changed, 171 insertions(+), 10 deletions(-) create mode 100755 test_regress/t/t_constraint_pure.py create mode 100644 test_regress/t/t_constraint_pure.v create mode 100644 test_regress/t/t_constraint_pure_missing_bad.out create mode 100755 test_regress/t/t_constraint_pure_missing_bad.py create mode 100644 test_regress/t/t_constraint_pure_missing_bad.v create mode 100644 test_regress/t/t_constraint_pure_nonabs_bad.out create mode 100755 test_regress/t/t_constraint_pure_nonabs_bad.py create mode 100644 test_regress/t/t_constraint_pure_nonabs_bad.v diff --git a/Changes b/Changes index de90148a5..17b5201c5 100644 --- a/Changes +++ b/Changes @@ -15,6 +15,7 @@ Verilator 5.031 devel * Support queue's assignment `push_back/push_front('{})` (#5585) (#5586). [Yilou Wang] * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] +* Support `pure constraint`. * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index e4b3cee54..49442e9e7 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1026,7 +1026,8 @@ class AstConstraint final : public AstNode { // Constraint // @astgen op1 := itemsp : List[AstNode] string m_name; // Name of constraint - bool m_isStatic = false; // static constraint + bool m_isKwdPure = false; // Pure constraint + bool m_isStatic = false; // Static constraint public: AstConstraint(FileLine* fl, const string& name, AstNode* itemsp) : ASTGEN_SUPER_Constraint(fl) @@ -1034,11 +1035,15 @@ public: this->addItemsp(itemsp); } ASTGEN_MEMBERS_AstConstraint; + void dump(std::ostream& str) const override; + void dumpJson(std::ostream& str) const override; string name() const override VL_MT_STABLE { return m_name; } // * = Scope name bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool maybePointedTo() const override VL_MT_SAFE { return true; } bool same(const AstNode* /*samep*/) const override { return true; } + void isKwdPure(bool flag) { m_isKwdPure = flag; } + bool isKwdPure() const { return m_isKwdPure; } void isStatic(bool flag) { m_isStatic = flag; } bool isStatic() const { return m_isStatic; } }; diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 326a3d77d..00ca3aff5 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -366,7 +366,16 @@ void AstConsQueue::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, rhsIsValue); dumpJsonGen(str); } - +void AstConstraint::dump(std::ostream& str) const { + this->AstNode::dump(str); + if (isKwdPure()) str << " [KWDPURE]"; + if (isStatic()) str << " [STATIC]"; +} +void AstConstraint::dumpJson(std::ostream& str) const { + dumpJsonBoolFunc(str, isKwdPure); + dumpJsonBoolFunc(str, isStatic); + dumpJsonGen(str); +} AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) { bool success = false; if (literal[0] == '"') { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 41a449d33..af5c5c9b8 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2334,13 +2334,13 @@ class LinkDotResolveVisitor final : public VNVisitor { ++it) { if (AstNode* interfaceSubp = it->second->nodep()) { UINFO(8, indent() << " SymFunc " << interfaceSubp << endl); + const string impOrExtends + = baseClassp->isInterfaceClass() ? " implements " : " extends "; if (VN_IS(interfaceSubp, NodeFTask)) { const VSymEnt* const foundp = m_curSymp->findIdFlat(interfaceSubp->name()); const AstNodeFTask* const interfaceFuncp = VN_CAST(interfaceSubp, NodeFTask); if (!interfaceFuncp || !interfaceFuncp->pureVirtual()) continue; bool existsInChild = foundp && !foundp->imported(); - const string impOrExtends - = baseClassp->isInterfaceClass() ? " implements " : " extends "; if (!existsInChild && !implementsClassp->isInterfaceClass()) { implementsClassp->v3error( "Class " << implementsClassp->prettyNameQ() << impOrExtends @@ -2368,6 +2368,25 @@ class LinkDotResolveVisitor final : public VNVisitor { } m_ifClassImpNames.emplace(interfaceSubp->name(), interfaceSubp); } + if (VN_IS(interfaceSubp, Constraint)) { + const VSymEnt* const foundp = m_curSymp->findIdFlat(interfaceSubp->name()); + const AstConstraint* const interfaceFuncp = VN_CAST(interfaceSubp, Constraint); + if (!interfaceFuncp || !interfaceFuncp->isKwdPure()) continue; + bool existsInChild = foundp && !foundp->imported(); + if (!existsInChild && !implementsClassp->isInterfaceClass() + && !implementsClassp->isVirtual()) { + implementsClassp->v3error( + "Class " << implementsClassp->prettyNameQ() << impOrExtends + << baseClassp->prettyNameQ() + << " but is missing constraint implementation for " + << interfaceSubp->prettyNameQ() + << " (IEEE 1800-2023 18.5.2)\n" + << implementsClassp->warnContextPrimary() << '\n' + << interfaceSubp->warnOther() + << "... Location of interface class's pure constraint\n" + << interfaceSubp->warnContextSecondary()); + } + } } } } diff --git a/src/V3WidthCommit.cpp b/src/V3WidthCommit.cpp index 1c9e1640f..e4a6e3f6c 100644 --- a/src/V3WidthCommit.cpp +++ b/src/V3WidthCommit.cpp @@ -162,6 +162,18 @@ private: nodep->replaceWith(nodep->lhsp()->unlinkFrBack()); VL_DO_DANGLING(pushDeletep(nodep), nodep); } + void visit(AstConstraint* nodep) override { + iterateChildren(nodep); + editDType(nodep); + { + const AstClass* const classp = VN_CAST(m_modp, Class); + if (nodep->isKwdPure() + && (!classp || (!classp->isInterfaceClass() && !classp->isVirtual()))) { + nodep->v3error("Illegal to have 'pure constraint' in non-abstract class" + " (IEEE 1800-2023 18.5.2)"); + } + } + } void visit(AstNodeDType* nodep) override { // Note some specific dtypes have unique visitors visitIterateNodeDType(nodep); diff --git a/src/verilog.y b/src/verilog.y index d7058a9bc..73bb8967a 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7391,8 +7391,7 @@ class_constraint: // ==IEEE: class_constraint { $$ = $4; $$->isStatic($1); SYMP->popScope($4); BBUNSUP($1, "Unsupported: extern constraint"); } | yPURE constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $4; $$->isStatic($1); SYMP->popScope($4); - BBUNSUP($1, "Unsupported: pure constraint"); } + { $$ = $4; $$->isKwdPure($1); $$->isStatic($1); SYMP->popScope($4); } ; constraintIdNew: // IEEE: id part of class_constraint diff --git a/test_regress/t/t_constraint_pure.py b/test_regress/t/t_constraint_pure.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_constraint_pure.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_pure.v b/test_regress/t/t_constraint_pure.v new file mode 100644 index 000000000..c3fc3f64a --- /dev/null +++ b/test_regress/t/t_constraint_pure.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +virtual class Base; + pure constraint raint; +endclass + +class Cls extends Base; + rand int b2; + constraint raint { b2 == 5; } +endclass + +virtual class Virt extends Base; + // No constraint needed +endclass + +module t; + initial begin + Cls c = new; + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_constraint_pure_missing_bad.out b/test_regress/t/t_constraint_pure_missing_bad.out new file mode 100644 index 000000000..e9b226c01 --- /dev/null +++ b/test_regress/t/t_constraint_pure_missing_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_pure_missing_bad.v:11:1: Class 'Cls' extends 'Base' but is missing constraint implementation for 'raint' (IEEE 1800-2023 18.5.2) + 11 | class Cls extends Base; + | ^~~~~ + t/t_constraint_pure_missing_bad.v:8:21: ... Location of interface class's pure constraint + 8 | pure constraint raint; + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_constraint_pure_missing_bad.py b/test_regress/t/t_constraint_pure_missing_bad.py new file mode 100755 index 000000000..e33e10acf --- /dev/null +++ b/test_regress/t/t_constraint_pure_missing_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_constraint_pure_missing_bad.v b/test_regress/t/t_constraint_pure_missing_bad.v new file mode 100644 index 000000000..9d81382d5 --- /dev/null +++ b/test_regress/t/t_constraint_pure_missing_bad.v @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +virtual class Base; + pure constraint raint; +endclass + +class Cls extends Base; + // Bad: Missing 'constraint raint' +endclass + +module t; +endmodule diff --git a/test_regress/t/t_constraint_pure_nonabs_bad.out b/test_regress/t/t_constraint_pure_nonabs_bad.out new file mode 100644 index 000000000..039a415a0 --- /dev/null +++ b/test_regress/t/t_constraint_pure_nonabs_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_constraint_pure_nonabs_bad.v:8:21: Illegal to have 'pure constraint' in non-abstract class (IEEE 1800-2023 18.5.2) + : ... note: In instance 't' + 8 | pure constraint raintBad; + | ^~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_constraint_pure_nonabs_bad.py b/test_regress/t/t_constraint_pure_nonabs_bad.py new file mode 100755 index 000000000..e33e10acf --- /dev/null +++ b/test_regress/t/t_constraint_pure_nonabs_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_constraint_pure_nonabs_bad.v b/test_regress/t/t_constraint_pure_nonabs_bad.v new file mode 100644 index 000000000..0ea5366d2 --- /dev/null +++ b/test_regress/t/t_constraint_pure_nonabs_bad.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class NonAsbstract; + pure constraint raintBad; // Bad: Not in abstract class +endclass + +module t; +endmodule diff --git a/test_regress/t/t_randomize_extern.out b/test_regress/t/t_randomize_extern.out index a56aaa409..91ae91a9d 100644 --- a/test_regress/t/t_randomize_extern.out +++ b/test_regress/t/t_randomize_extern.out @@ -1,10 +1,7 @@ -%Error-UNSUPPORTED: t/t_randomize_extern.v:8:4: Unsupported: pure constraint - 8 | pure constraint pur; - | ^~~~ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error-UNSUPPORTED: t/t_randomize_extern.v:17:4: Unsupported: extern constraint 17 | extern constraint ex; | ^~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error-UNSUPPORTED: t/t_randomize_extern.v:21:1: Unsupported: extern constraint 21 | constraint Packet::ex { header == 2; } | ^~~~~~~~~~ From d230ccd716636bd57791ca286b26f1e699adf56b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 12:26:48 -0500 Subject: [PATCH 033/171] Add error on `solve before` of `randc` variable. --- Changes | 1 + src/V3Randomize.cpp | 9 +++++++++ test_regress/t/t_randomize_before_randc_bad.out | 5 +++++ test_regress/t/t_randomize_before_randc_bad.py | 16 ++++++++++++++++ test_regress/t/t_randomize_before_randc_bad.v | 15 +++++++++++++++ 5 files changed, 46 insertions(+) create mode 100644 test_regress/t/t_randomize_before_randc_bad.out create mode 100755 test_regress/t/t_randomize_before_randc_bad.py create mode 100644 test_regress/t/t_randomize_before_randc_bad.v diff --git a/Changes b/Changes index 17b5201c5..706bc0d76 100644 --- a/Changes +++ b/Changes @@ -20,6 +20,7 @@ Verilator 5.031 devel * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Add error on `solve before` of `randc` variable. * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 24a5a41bb..4558423ff 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -401,6 +401,15 @@ class RandomizeMarkVisitor final : public VNVisitor { } } } + void visit(AstConstraintBefore* nodep) override { + nodep->foreach([&](AstVarRef* const refp) { + if (refp->varp() && refp->varp()->isRandC()) { + nodep->v3error( + "Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9)"); + } + }); + iterateChildrenConst(nodep); + } void visit(AstConstraintExpr* nodep) override { VL_RESTORER(m_constraintExprp); m_constraintExprp = nodep; diff --git a/test_regress/t/t_randomize_before_randc_bad.out b/test_regress/t/t_randomize_before_randc_bad.out new file mode 100644 index 000000000..5392c2b5f --- /dev/null +++ b/test_regress/t/t_randomize_before_randc_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_randomize_before_randc_bad.v:11:29: Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9) + : ... note: In instance 't' + 11 | constraint raint2_bad { solve b1 before b2; } + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_before_randc_bad.py b/test_regress/t/t_randomize_before_randc_bad.py new file mode 100755 index 000000000..30c3d4f77 --- /dev/null +++ b/test_regress/t/t_randomize_before_randc_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_randomize_before_randc_bad.v b/test_regress/t/t_randomize_before_randc_bad.v new file mode 100644 index 000000000..effeefd30 --- /dev/null +++ b/test_regress/t/t_randomize_before_randc_bad.v @@ -0,0 +1,15 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls1; + rand bit b1; + randc int b2; + + constraint raint2_bad { solve b1 before b2; } // BAD no randc vars here +endclass + +module t (/*AUTOARG*/); +endmodule From 4969125e5aff8a51a6a87926779e32459cbbf698 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 12:45:55 -0500 Subject: [PATCH 034/171] Add error on soft constraints of randc --- Changes | 2 +- src/V3AstNodeOther.h | 4 +- src/V3AstNodes.cpp | 10 +++++ src/V3Randomize.cpp | 39 ++++++++++++------- .../t/t_randomize_before_randc_bad.out | 4 +- test_regress/t/t_randomize_soft_randc_bad.out | 5 +++ test_regress/t/t_randomize_soft_randc_bad.py | 16 ++++++++ test_regress/t/t_randomize_soft_randc_bad.v | 14 +++++++ 8 files changed, 75 insertions(+), 19 deletions(-) create mode 100644 test_regress/t/t_randomize_soft_randc_bad.out create mode 100755 test_regress/t/t_randomize_soft_randc_bad.py create mode 100644 test_regress/t/t_randomize_soft_randc_bad.v diff --git a/Changes b/Changes index 706bc0d76..acf36fcbd 100644 --- a/Changes +++ b/Changes @@ -20,7 +20,7 @@ Verilator 5.031 devel * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] -* Add error on `solve before` of `randc` variable. +* Add error on `solve before` or soft constraints of `randc` variable. * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 49442e9e7..68fdbcd31 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2763,14 +2763,16 @@ public: class AstConstraintExpr final : public AstNodeStmt { // Constraint expression // @astgen op1 := exprp : AstNodeExpr - bool m_isSoft = false; // Soft constraint expression bool m_isDisableSoft = false; // Disable soft constraint expression + bool m_isSoft = false; // Soft constraint expression public: AstConstraintExpr(FileLine* fl, AstNodeExpr* exprp) : ASTGEN_SUPER_ConstraintExpr(fl) { this->exprp(exprp); } ASTGEN_MEMBERS_AstConstraintExpr; + void dump(std::ostream& str) const override; + void dumpJson(std::ostream& str) const override; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool same(const AstNode* /*samep*/) const override { return true; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 00ca3aff5..5a2ba837f 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -376,6 +376,16 @@ void AstConstraint::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, isStatic); dumpJsonGen(str); } +void AstConstraintExpr::dump(std::ostream& str) const { + this->AstNode::dump(str); + if (isDisableSoft()) str << " [DISSOFT]"; + if (isSoft()) str << " [SOFT]"; +} +void AstConstraintExpr::dumpJson(std::ostream& str) const { + dumpJsonBoolFunc(str, isDisableSoft); + dumpJsonBoolFunc(str, isSoft); + dumpJsonGen(str); +} AstConst* AstConst::parseParamLiteral(FileLine* fl, const string& literal) { bool success = false; if (literal[0] == '"') { diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 4558423ff..9b059d512 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -131,7 +131,9 @@ class RandomizeMarkVisitor final : public VNVisitor { BaseToDerivedMap m_baseToDerivedMap; // Mapping from base classes to classes that extend them AstClass* m_classp = nullptr; // Current class - AstNode* m_constraintExprp = nullptr; // Current constraint expression + AstConstraintBefore* m_constraintBeforep = nullptr; // Current before constraint + AstConstraintExpr* m_constraintExprp = nullptr; // Current constraint expression + AstNode* m_constraintExprGenp = nullptr; // Current constraint or constraint if expression AstNodeModule* m_modp; // Current module AstNodeStmt* m_stmtp = nullptr; // Current statement std::set m_staticRefs; // References to static variables under `with` clauses @@ -402,50 +404,57 @@ class RandomizeMarkVisitor final : public VNVisitor { } } void visit(AstConstraintBefore* nodep) override { - nodep->foreach([&](AstVarRef* const refp) { - if (refp->varp() && refp->varp()->isRandC()) { - nodep->v3error( - "Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9)"); - } - }); + VL_RESTORER(m_constraintBeforep); + m_constraintBeforep = nodep; iterateChildrenConst(nodep); } void visit(AstConstraintExpr* nodep) override { VL_RESTORER(m_constraintExprp); m_constraintExprp = nodep; + VL_RESTORER(m_constraintExprGenp); + m_constraintExprGenp = nodep; iterateChildrenConst(nodep); } void visit(AstConstraintIf* nodep) override { { - VL_RESTORER(m_constraintExprp); - m_constraintExprp = nodep; + VL_RESTORER(m_constraintExprGenp); + m_constraintExprGenp = nodep; iterateConst(nodep->condp()); } iterateAndNextConstNull(nodep->thensp()); iterateAndNextConstNull(nodep->elsesp()); } void visit(AstNodeVarRef* nodep) override { - if (!m_constraintExprp) return; + if (nodep->varp()->isRandC()) { + if (m_constraintExprp && m_constraintExprp->isSoft()) { + nodep->v3error( + "Randc variables not allowed in 'constraint soft' (IEEE 1800-2023 18.5.13.1)"); + } else if (m_constraintBeforep) { + nodep->v3error( + "Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9)"); + } + } + if (!m_constraintExprGenp) return; if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep); if (!nodep->varp()->rand().isRandomizable()) return; - for (AstNode* backp = nodep; backp != m_constraintExprp && !backp->user1(); + for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); backp = backp->backp()) backp->user1(true); } void visit(AstMemberSel* nodep) override { - if (!m_constraintExprp) return; + if (!m_constraintExprGenp) return; if (VN_IS(nodep->fromp(), LambdaArgRef)) { if (!nodep->varp()->rand().isRandomizable()) return; - for (AstNode* backp = nodep; backp != m_constraintExprp && !backp->user1(); + for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); backp = backp->backp()) backp->user1(true); } } void visit(AstArraySel* nodep) override { - if (!m_constraintExprp) return; - for (AstNode* backp = nodep; backp != m_constraintExprp && !backp->user1(); + if (!m_constraintExprGenp) return; + for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); backp = backp->backp()) backp->user1(true); iterateChildrenConst(nodep); diff --git a/test_regress/t/t_randomize_before_randc_bad.out b/test_regress/t/t_randomize_before_randc_bad.out index 5392c2b5f..9480b7624 100644 --- a/test_regress/t/t_randomize_before_randc_bad.out +++ b/test_regress/t/t_randomize_before_randc_bad.out @@ -1,5 +1,5 @@ -%Error: t/t_randomize_before_randc_bad.v:11:29: Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9) +%Error: t/t_randomize_before_randc_bad.v:11:45: Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9) : ... note: In instance 't' 11 | constraint raint2_bad { solve b1 before b2; } - | ^~~~~ + | ^~ %Error: Exiting due to diff --git a/test_regress/t/t_randomize_soft_randc_bad.out b/test_regress/t/t_randomize_soft_randc_bad.out new file mode 100644 index 000000000..a1646e725 --- /dev/null +++ b/test_regress/t/t_randomize_soft_randc_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_randomize_soft_randc_bad.v:10:28: Randc variables not allowed in 'constraint soft' (IEEE 1800-2023 18.5.13.1) + : ... note: In instance 't' + 10 | constraint c_bad { soft rc > 4; } + | ^~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_soft_randc_bad.py b/test_regress/t/t_randomize_soft_randc_bad.py new file mode 100755 index 000000000..30c3d4f77 --- /dev/null +++ b/test_regress/t/t_randomize_soft_randc_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_randomize_soft_randc_bad.v b/test_regress/t/t_randomize_soft_randc_bad.v new file mode 100644 index 000000000..f10a49f34 --- /dev/null +++ b/test_regress/t/t_randomize_soft_randc_bad.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls1; + randc int rc; + + constraint c_bad { soft rc > 4; } // Bad, no soft on randc +endclass + +module t (/*AUTOARG*/); +endmodule From f073b278f91d87c27c3a2a1b1aa3560880264eea Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sat, 9 Nov 2024 18:14:19 +0000 Subject: [PATCH 035/171] Balance concatenations in DFG (#5598) The DFG peephole pass converts all associative trees into right leaning, which is good for simplifying pattern recognition, but can lead to an excessive amount of wide intermediate results being constructed for right leaning concatenations. Add a new pass to balance concatenation trees by trying to: - Create VL_EDATASIZE (32-bit) sub-terms, so words can then be packed easily afterwards - Try to ensure the operands of a concat are roughly the same width within a concatenation tree. This does not yield the shortest tree, but it ensures it has many sub-nodes that are small enough to fit into machine registers. This can eliminate a lot of wide intermediate results, which would need temporaries, and also increases ILP within sub-expressions (assuming the C compiler can't figure that out itself). This is over 2x run-time speedup on the high_perf configuration of VeeR EH2 (which you could arguably also get with -fno-dfg, but oh well). --- src/CMakeLists.txt | 1 + src/Makefile_obj.in | 1 + src/V3Dfg.h | 3 + src/V3DfgBalanceTrees.cpp | 197 +++++++++++++++++++++++++++ src/V3DfgOptimizer.cpp | 4 +- src/V3DfgOptimizer.h | 2 +- src/V3DfgPasses.cpp | 11 +- src/V3DfgPasses.h | 16 ++- src/Verilator.cpp | 4 +- test_regress/t/t_dfg_balance_cats.py | 21 +++ test_regress/t/t_dfg_balance_cats.v | 35 +++++ test_regress/t/t_opt_const_dfg.py | 2 +- 12 files changed, 289 insertions(+), 8 deletions(-) create mode 100644 src/V3DfgBalanceTrees.cpp create mode 100755 test_regress/t/t_dfg_balance_cats.py create mode 100644 test_regress/t/t_dfg_balance_cats.v diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e0b1792a6..9049fc215 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -224,6 +224,7 @@ set(COMMON_SOURCES V3Descope.cpp V3Dfg.cpp V3DfgAstToDfg.cpp + V3DfgBalanceTrees.cpp V3DfgCache.cpp V3DfgDecomposition.cpp V3DfgDfgToAst.cpp diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index d29baa840..0e972fc71 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -237,6 +237,7 @@ RAW_OBJS_PCH_ASTNOMT = \ V3Descope.o \ V3Dfg.o \ V3DfgAstToDfg.o \ + V3DfgBalanceTrees.o \ V3DfgCache.o \ V3DfgDecomposition.o \ V3DfgDfgToAst.o \ diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 5fab278ee..8b0978b97 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -274,6 +274,9 @@ public: // Predicate: has 1 or more sinks bool hasSinks() const { return m_sinksp != nullptr; } + // Predicate: has precisely 1 sink + bool hasSingleSink() const { return m_sinksp && !m_sinksp->m_nextp; } + // Predicate: has 2 or more sinks bool hasMultipleSinks() const { return m_sinksp && m_sinksp->m_nextp; } diff --git a/src/V3DfgBalanceTrees.cpp b/src/V3DfgBalanceTrees.cpp new file mode 100644 index 000000000..6b5eca2d8 --- /dev/null +++ b/src/V3DfgBalanceTrees.cpp @@ -0,0 +1,197 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Balance associative op trees in DfgGraphs +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2024 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 +// +//************************************************************************* +// +// - Convert concatenation trees into balanced form +// +//************************************************************************* + +#include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT + +#include "V3Dfg.h" +#include "V3DfgPasses.h" + +VL_DEFINE_DEBUG_FUNCTIONS; + +class DfgBalanceTrees final { + // We keep the expressions, together with their offsets within a concatenation tree + struct ConcatTerm final { + DfgVertex* vtxp = nullptr; + size_t offset = 0; + + ConcatTerm() = default; + ConcatTerm(DfgVertex* vtxp, size_t offset) + : vtxp{vtxp} + , offset{offset} {} + }; + + DfgGraph& m_dfg; // The graph being processed + V3DfgBalanceTreesContext& m_ctx; // The optimization context for stats + + // Is the given vertex the root of a tree (of potentially size 1), of the given type? + template + static bool isRoot(const DfgVertex& vtx) { + static_assert(std::is_base_of::value, + "'Vertex' must be a 'DfgVertexBinary'"); + if (!vtx.is()) return false; + // Has a single sink, and that sink is not another vertex of the same type + return vtx.hasSingleSink() && !vtx.findSink(); + } + + // Recursive implementation of 'gatherTerms' below. + template + static void gatherTermsImpl(DfgVertex* vtxp, std::vector& terms) { + // Base case: different type, or multiple sinks -> it's a term + if (!vtxp->is() || vtxp->hasMultipleSinks()) { + terms.emplace_back(vtxp); + return; + } + // Recursive case: gather sub terms, right to right + DfgVertexBinary* const binp = vtxp->as(); + gatherTermsImpl(binp->rhsp(), terms); + gatherTermsImpl(binp->lhsp(), terms); + } + + // Gather terms in the tree of given type, rooted at the given vertex. + // Results are right to left, that is, index 0 in the returned vector + // is the rightmost term, index size()-1 is the leftmost term. + template + static std::vector gatherTerms(Vertex& root) { + static_assert(std::is_base_of::value, + "'Vertex' must be a 'DfgVertexBinary'"); + std::vector terms; + gatherTermsImpl(root.rhsp(), terms); + gatherTermsImpl(root.lhsp(), terms); + return terms; + } + + // Construct a balanced concatenation from the given terms, + // between indices begin (inclusive), and end (exclusive). + // Note term[end].offset must be valid. term[end].vtxp is + // never referenced. + DfgVertex* constructConcat(const std::vector& terms, const size_t begin, + const size_t end) { + UASSERT(end < terms.size(), "Invalid end"); + UASSERT(begin < end, "Invalid range"); + // Base case: just return the term + if (end == begin + 1) return terms[begin].vtxp; + + // Recursive case: + // Compute the mid-point, trying to create roughly equal width intermediates + const size_t width = terms[end].offset - terms[begin].offset; + const size_t midOffset = width / 2 + terms[begin].offset; + const auto beginIt = terms.begin() + begin; + const auto endIt = terms.begin() + end; + const auto midIt = std::lower_bound(beginIt + 1, endIt - 1, midOffset, // + [&](const ConcatTerm& term, size_t value) { // + return term.offset < value; + }); + const size_t mid = begin + std::distance(beginIt, midIt); + UASSERT(begin < mid && mid < end, "Must make some progress"); + // Construct the subtrees + DfgVertex* const rhsp = constructConcat(terms, begin, mid); + DfgVertex* const lhsp = constructConcat(terms, mid, end); + // Construct new node + AstNodeDType* const dtypep = DfgVertex::dtypeForWidth(lhsp->width() + rhsp->width()); + DfgConcat* const newp = new DfgConcat{m_dfg, lhsp->fileline(), dtypep}; + newp->rhsp(rhsp); + newp->lhsp(lhsp); + return newp; + } + + // Delete unused tree rooted at the given vertex + void deleteTree(DfgVertexBinary* const vtxp) { + UASSERT_OBJ(!vtxp->hasSinks(), vtxp, "Trying to remove used vertex"); + DfgVertexBinary* const lhsp = vtxp->lhsp()->cast(); + DfgVertexBinary* const rhsp = vtxp->rhsp()->cast(); + VL_DO_DANGLING(vtxp->unlinkDelete(m_dfg), vtxp); + if (lhsp && !lhsp->hasSinks()) deleteTree(lhsp); + if (rhsp && !rhsp->hasSinks()) deleteTree(rhsp); + } + + void balanceConcat(DfgConcat* const rootp) { + // Gather all input vertices of the tree + const std::vector vtxps = gatherTerms(*rootp); + // Don't bother with trivial trees + if (vtxps.size() <= 3) return; + + // Construct the terms Vector that we are going to do processing on + std::vector terms(vtxps.size() + 1); + // These are redundant (constructor does the same), but here they are for clarity + terms[0].offset = 0; + terms[vtxps.size()].vtxp = nullptr; + for (size_t i = 0; i < vtxps.size(); ++i) { + terms[i].vtxp = vtxps[i]; + terms[i + 1].offset = terms[i].offset + vtxps[i]->width(); + } + + // Round 1: try to create terms ending on VL_EDATASIZE boundaries. + // This ensures we pack bits within a VL_EDATASIZE first is possible, + // and then hopefully we can just assemble VL_EDATASIZE words afterward. + std::vector terms2; + { + terms2.reserve(terms.size()); + + size_t begin = 0; // Start of current range considered + size_t end = 0; // End of current range considered + size_t offset = 0; // Offset of current range considered + + // Create a term from the current range + const auto makeTerm = [&]() { + DfgVertex* const vtxp = constructConcat(terms, begin, end); + terms2.emplace_back(vtxp, offset); + offset += vtxp->width(); + begin = end; + }; + + // Create all terms ending on a boundary. + while (++end < terms.size() - 1) { + if (terms[end].offset % VL_EDATASIZE == 0) makeTerm(); + } + // Final term. Loop condition above ensures this always exists, + // and might or might not be on a boundary. + makeTerm(); + // Sentinel term + terms2.emplace_back(nullptr, offset); + // should have ended up with the same number of bits at least... + UASSERT(terms2.back().offset == terms.back().offset, "Inconsitent terms"); + } + + // Round 2: Combine the partial terms + rootp->replaceWith(constructConcat(terms2, 0, terms2.size() - 1)); + VL_DO_DANGLING(deleteTree(rootp), rootp); + + ++m_ctx.m_balancedConcats; + } + + DfgBalanceTrees(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) + : m_dfg{dfg} + , m_ctx{ctx} { + // Find all roots + std::vector rootps; + for (DfgVertex& vtx : dfg.opVertices()) { + if (isRoot(vtx)) rootps.emplace_back(vtx.as()); + } + // Balance them + for (DfgConcat* const rootp : rootps) balanceConcat(rootp); + } + +public: + static void apply(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) { DfgBalanceTrees{dfg, ctx}; } +}; + +void V3DfgPasses::balanceTrees(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) { + DfgBalanceTrees::apply(dfg, ctx); +} diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index d6c6f1f30..7297cdd85 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -236,7 +236,7 @@ void V3DfgOptimizer::extract(AstNetlist* netlistp) { V3Global::dumpCheckGlobalTree("dfg-extract", 0, dumpTreeEitherLevel() >= 3); } -void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label) { +void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label, bool lastInvocation) { UINFO(2, __FUNCTION__ << ": " << endl); // NODE STATE @@ -282,7 +282,7 @@ void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label) { for (auto& component : acyclicComponents) { if (dumpDfgLevel() >= 7) component->dumpDotFilePrefixed(ctx.prefix() + "source"); // Optimize the component - V3DfgPasses::optimize(*component, ctx); + V3DfgPasses::optimize(*component, ctx, lastInvocation); // Add back under the main DFG (we will convert everything back in one go) dfg->addGraph(*component); } diff --git a/src/V3DfgOptimizer.h b/src/V3DfgOptimizer.h index 067b5e801..df67c3e53 100644 --- a/src/V3DfgOptimizer.h +++ b/src/V3DfgOptimizer.h @@ -29,7 +29,7 @@ namespace V3DfgOptimizer { void extract(AstNetlist*) VL_MT_DISABLED; // Optimize the design -void optimize(AstNetlist*, const string& label) VL_MT_DISABLED; +void optimize(AstNetlist*, const string& label, bool lastInvocation) VL_MT_DISABLED; } // namespace V3DfgOptimizer #endif // Guard diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index d67642e8c..5b3f04041 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -42,6 +42,11 @@ V3DfgEliminateVarsContext::~V3DfgEliminateVarsContext() { m_varsRemoved); } +V3DfgBalanceTreesContext::~V3DfgBalanceTreesContext() { + V3Stats::addStat("Optimizations, DFG " + m_label + " BalanceTrees, concat trees balanced", + m_balancedConcats); +} + static std::string getPrefix(const std::string& label) { if (label.empty()) return ""; std::string str = VString::removeWhitespace(label); @@ -332,7 +337,7 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) { for (AstVar* const varp : replacedVariables) varp->unlinkFrBack()->deleteTree(); } -void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx) { +void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx, bool lastInvocation) { // There is absolutely nothing useful we can do with a graph of size 2 or less if (dfg.size() <= 2) return; @@ -360,6 +365,10 @@ void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx) { } // Accumulate patterns for reporting if (v3Global.opt.stats()) ctx.m_patternStats.accumulate(dfg); + // The peephole pass covnerts all trees to right leaning, so only do this on the last DFG run. + if (lastInvocation) { + apply(4, "balanceTrees", [&]() { balanceTrees(dfg, ctx.m_balanceTreesContext); }); + } apply(4, "regularize", [&]() { regularize(dfg, ctx.m_regularizeContext); }); if (dumpDfgLevel() >= 8) dfg.dumpDotAllVarConesPrefixed(ctx.prefix() + "optimized"); } diff --git a/src/V3DfgPasses.h b/src/V3DfgPasses.h index 2b1e08aa6..d893c84ce 100644 --- a/src/V3DfgPasses.h +++ b/src/V3DfgPasses.h @@ -68,6 +68,17 @@ public: ~V3DfgEliminateVarsContext() VL_MT_DISABLED; }; +class V3DfgBalanceTreesContext final { + const std::string m_label; // Label to apply to stats + +public: + VDouble0 m_balancedConcats; // Number of temporaries introduced + + explicit V3DfgBalanceTreesContext(const std::string& label) + : m_label{label} {} + ~V3DfgBalanceTreesContext() VL_MT_DISABLED; +}; + class V3DfgOptimizationContext final { const std::string m_label; // Label to add to stats, etc. const std::string m_prefix; // Prefix to add to file dumps (derived from label) @@ -92,6 +103,7 @@ public: V3DfgPeepholeContext m_peepholeContext{m_label}; V3DfgRegularizeContext m_regularizeContext{m_label}; V3DfgEliminateVarsContext m_eliminateVarsContext{m_label}; + V3DfgBalanceTreesContext m_balanceTreesContext{m_label}; V3DfgPatternStats m_patternStats; @@ -112,7 +124,7 @@ namespace V3DfgPasses { DfgGraph* astToDfg(AstModule&, V3DfgOptimizationContext&) VL_MT_DISABLED; // Optimize the given DfgGraph -void optimize(DfgGraph&, V3DfgOptimizationContext&) VL_MT_DISABLED; +void optimize(DfgGraph&, V3DfgOptimizationContext&, bool lastInvocation) VL_MT_DISABLED; // Convert DfgGraph back into Ast, and insert converted graph back into its parent module. // Returns the parent module. @@ -134,6 +146,8 @@ void regularize(DfgGraph&, V3DfgRegularizeContext&) VL_MT_DISABLED; void removeUnused(DfgGraph&) VL_MT_DISABLED; // Eliminate (remove or replace) redundant variables. Also removes resulting unused logic. void eliminateVars(DfgGraph&, V3DfgEliminateVarsContext&) VL_MT_DISABLED; +// Make computation trees balanced +void balanceTrees(DfgGraph&, V3DfgBalanceTreesContext&) VL_MT_DISABLED; } // namespace V3DfgPasses diff --git a/src/Verilator.cpp b/src/Verilator.cpp index d6b58ea9c..92d3f53de 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -286,7 +286,7 @@ static void process() { if (v3Global.opt.fDfgPreInline()) { // Pre inline DFG optimization - V3DfgOptimizer::optimize(v3Global.rootp(), "pre inline"); + V3DfgOptimizer::optimize(v3Global.rootp(), "pre inline", /* lastInvocation: */ false); } if (!(v3Global.opt.serializeOnly() && !v3Global.opt.flatten())) { @@ -303,7 +303,7 @@ static void process() { if (v3Global.opt.fDfgPostInline()) { // Post inline DFG optimization - V3DfgOptimizer::optimize(v3Global.rootp(), "post inline"); + V3DfgOptimizer::optimize(v3Global.rootp(), "post inline", /* lastInvocation: */ true); } // --PRE-FLAT OPTIMIZATIONS------------------ diff --git a/test_regress/t/t_dfg_balance_cats.py b/test_regress/t/t_dfg_balance_cats.py new file mode 100755 index 000000000..0a4055967 --- /dev/null +++ b/test_regress/t/t_dfg_balance_cats.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=["--stats"]) + +test.file_grep(test.stats, + r' Optimizations, DFG pre inline BalanceTrees, concat trees balanced\s+(\d+)', 0) +test.file_grep(test.stats, + r' Optimizations, DFG post inline BalanceTrees, concat trees balanced\s+(\d+)', 1) + +test.passes() diff --git a/test_regress/t/t_dfg_balance_cats.v b/test_regress/t/t_dfg_balance_cats.v new file mode 100644 index 000000000..4562ca1e5 --- /dev/null +++ b/test_regress/t/t_dfg_balance_cats.v @@ -0,0 +1,35 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// verilator lint_off UNOPTFLAT + +module t(i, o); + localparam N = 2000; // Deliberately not multiple of 32 + + input i; + wire [N-1:0] i; + + output o; + wire [N-1:0] o; + + for (genvar n = 0 ; n + 31 < N ; n += 32) begin + assign o[n+ 0 +: 1] = i[(N-1-n)- 0 -: 1]; + assign o[n+ 1 +: 1] = i[(N-1-n)- 1 -: 1]; + assign o[n+ 2 +: 2] = i[(N-1-n)- 2 -: 2]; + assign o[n+ 4 +: 4] = i[(N-1-n)- 4 -: 4]; + assign o[n+ 8 +: 8] = i[(N-1-n)- 8 -: 8]; + assign o[n+16 +: 8] = i[(N-1-n)-16 -: 8]; + assign o[n+24 +: 4] = i[(N-1-n)-24 -: 4]; + assign o[n+28 +: 2] = i[(N-1-n)-28 -: 2]; + assign o[n+30 +: 1] = i[(N-1-n)-30 -: 1]; + assign o[n+31 +: 1] = i[(N-1-n)-31 -: 1]; + end + + for (genvar n = N / 32 * 32; n < N ; ++n) begin + assign o[n] = i[N-1-n]; + end + +endmodule diff --git a/test_regress/t/t_opt_const_dfg.py b/test_regress/t/t_opt_const_dfg.py index eed838d28..e46719f23 100755 --- a/test_regress/t/t_opt_const_dfg.py +++ b/test_regress/t/t_opt_const_dfg.py @@ -17,6 +17,6 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats", test.t_dir + "/t_ test.execute() if test.vlt: - test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 40) + test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 39) test.passes() From c7a7965c4966946e87689018505d9d0d22b062ed Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 16:49:34 -0500 Subject: [PATCH 036/171] Rename identifer token --- src/verilog.y | 2 +- test_regress/t/t_class_param_comma_bad.out | 10 +++++----- test_regress/t/t_inst_param_comma_bad.out | 12 ++++++------ test_regress/t/t_lint_implicit_type_bad.out | 2 +- test_regress/t/t_lint_pkg_colon_bad.out | 2 +- test_regress/t/t_param_type_bad.out | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 73bb8967a..cb8883b89 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -442,7 +442,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yaID__ETC "IDENTIFIER" %token yaID__CC "IDENTIFIER-::" %token yaID__LEX "IDENTIFIER-in-lex" -%token yaID__aTYPE "TYPE-IDENTIFIER" +%token yaID__aTYPE "IDENTIFIER-for-type" // Can't predecode aFUNCTION, can declare after use // Can't predecode aINTERFACE, can declare after use // Can't predecode aTASK, can declare after use diff --git a/test_regress/t/t_class_param_comma_bad.out b/test_regress/t/t_class_param_comma_bad.out index b7de6da25..a775e47c0 100644 --- a/test_regress/t/t_class_param_comma_bad.out +++ b/test_regress/t/t_class_param_comma_bad.out @@ -1,16 +1,16 @@ -%Error: t/t_class_param_comma_bad.v:16:22: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_class_param_comma_bad.v:16:22: syntax error, unexpected ')', expecting IDENTIFIER-for-type 16 | Cls #(.PARAMB(14),) ce; | ^ -%Error: t/t_class_param_comma_bad.v:17:13: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_class_param_comma_bad.v:17:13: syntax error, unexpected ')', expecting IDENTIFIER-for-type 17 | Cls #(14,) cf; | ^ -%Error: t/t_class_param_comma_bad.v:18:14: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_class_param_comma_bad.v:18:14: syntax error, unexpected ')', expecting IDENTIFIER-for-type 18 | Cls2 #(15,) cg; | ^ -%Error: t/t_class_param_comma_bad.v:19:23: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_class_param_comma_bad.v:19:23: syntax error, unexpected ')', expecting IDENTIFIER-for-type 19 | Cls2 #(.PARAMB(16),) ch; | ^ -%Error: t/t_class_param_comma_bad.v:20:23: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_class_param_comma_bad.v:20:23: syntax error, unexpected ')', expecting IDENTIFIER-for-type 20 | Cls2 #(.PARAMC(17),) ci; | ^ %Error: Exiting due to diff --git a/test_regress/t/t_inst_param_comma_bad.out b/test_regress/t/t_inst_param_comma_bad.out index a272b2577..0f1ad9b1a 100644 --- a/test_regress/t/t_inst_param_comma_bad.out +++ b/test_regress/t/t_inst_param_comma_bad.out @@ -1,19 +1,19 @@ -%Error: t/t_inst_param_comma_bad.v:35:15: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:35:15: syntax error, unexpected ')', expecting IDENTIFIER-for-type 35 | M #(.P(13),) m1( | ^ -%Error: t/t_inst_param_comma_bad.v:40:11: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:40:11: syntax error, unexpected ')', expecting IDENTIFIER-for-type 40 | M #(14,) m2 ( | ^ -%Error: t/t_inst_param_comma_bad.v:45:11: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:45:11: syntax error, unexpected ')', expecting IDENTIFIER-for-type 45 | M #(14,) m3 ( | ^ -%Error: t/t_inst_param_comma_bad.v:50:15: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:50:15: syntax error, unexpected ')', expecting IDENTIFIER-for-type 50 | N #(.P(13),) n1( | ^ -%Error: t/t_inst_param_comma_bad.v:55:11: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:55:11: syntax error, unexpected ')', expecting IDENTIFIER-for-type 55 | N #(14,) n2 ( | ^ -%Error: t/t_inst_param_comma_bad.v:60:11: syntax error, unexpected ')', expecting TYPE-IDENTIFIER +%Error: t/t_inst_param_comma_bad.v:60:11: syntax error, unexpected ')', expecting IDENTIFIER-for-type 60 | N #(14,) n3 ( | ^ %Error: Exiting due to diff --git a/test_regress/t/t_lint_implicit_type_bad.out b/test_regress/t/t_lint_implicit_type_bad.out index 8f0e6e645..27fc9c53d 100644 --- a/test_regress/t/t_lint_implicit_type_bad.out +++ b/test_regress/t/t_lint_implicit_type_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_lint_implicit_type_bad.v:11:11: syntax error, unexpected TYPE-IDENTIFIER +%Error: t/t_lint_implicit_type_bad.v:11:11: syntax error, unexpected IDENTIFIER-for-type 11 | assign imp_type_conflict = 1'b1; | ^~~~~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_lint_pkg_colon_bad.out b/test_regress/t/t_lint_pkg_colon_bad.out index 9058994fd..dacf56eda 100644 --- a/test_regress/t/t_lint_pkg_colon_bad.out +++ b/test_regress/t/t_lint_pkg_colon_bad.out @@ -2,7 +2,7 @@ 7 | module t (input mispkg::foo_t a); | ^~~~~~ ... For error description see https://verilator.org/warn/PKGNODECL?v=latest -%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting TYPE-IDENTIFIER +%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting IDENTIFIER-for-type 7 | module t (input mispkg::foo_t a); | ^~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_param_type_bad.out b/test_regress/t/t_param_type_bad.out index 528bd8fc5..2c7ea7959 100644 --- a/test_regress/t/t_param_type_bad.out +++ b/test_regress/t/t_param_type_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER, expecting IDENTIFIER or TYPE-IDENTIFIER or randomize +%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER, expecting IDENTIFIER or IDENTIFIER-for-type or randomize 9 | localparam type bad2 = 2; | ^ %Error: Exiting due to From 99e7dbc82ba2a6c7458fe1e9378d13d70c34329d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 17:15:41 -0500 Subject: [PATCH 037/171] Internals: Put unsupported nettypes into symbol table, so parse as idType --- src/verilog.y | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index cb8883b89..acee2bb3b 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -184,6 +184,14 @@ public: AstSenTree* createGlobalClockSenTree(FileLine* fl) { return createClockSenTree(fl, createGlobalClockParseRef(fl)); } + AstNode* createNettype(FileLine* fl, const string& name) { + // As nettypes are unsupported, we just alias to logic + AstTypedef* const nodep = new AstTypedef{fl, name, nullptr, VFlagChildDType{}, + new AstBasicDType{fl, VFlagLogicPacked{}, 1}}; + SYMP->reinsert(nodep); + PARSEP->tagNodep(nodep); + return nodep; + } AstNode* createTypedef(FileLine* fl, const string& name, AstNode* attrsp, AstNodeDType* basep, AstNodeRange* rangep) { AstTypedef* const nodep = new AstTypedef{fl, name, attrsp, VFlagChildDType{}, @@ -2572,25 +2580,25 @@ nettype_declaration: // IEEE: nettype_declaration/net_type_declaration // // Union of data_typeAny and nettype_identifier matching yNETTYPE data_typeNoRef /*cont*/ idAny/*nettype_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype"); } + { $$ = GRAMMARP->createNettype($3, *$3); BBUNSUP($1, "Unsupported: nettype"); } | yNETTYPE data_typeNoRef /*cont*/ idAny/*nettype_identifier*/ /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype with"); } + { $$ = GRAMMARP->createNettype($3, *$3); BBUNSUP($1, "Unsupported: nettype with"); } | yNETTYPE packageClassScopeE idAny packed_dimensionListE /*cont*/ idAny/*nettype_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype"); } + { $$ = GRAMMARP->createNettype($5, *$5); BBUNSUP($1, "Unsupported: nettype"); } | yNETTYPE packageClassScopeE idAny packed_dimensionListE /*cont*/ idAny/*nettype_identifier*/ /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype with"); } + { $$ = GRAMMARP->createNettype($5, *$5); BBUNSUP($1, "Unsupported: nettype with"); } | yNETTYPE packageClassScopeE idAny parameter_value_assignmentClass packed_dimensionListE /*cont*/ idAny/*nettype_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype"); } + { $$ = GRAMMARP->createNettype($6, *$6); BBUNSUP($1, "Unsupported: nettype"); } | yNETTYPE packageClassScopeE idAny parameter_value_assignmentClass packed_dimensionListE /*cont*/ idAny/*nettype_identifier*/ /*cont*/ yWITH__ETC packageClassScopeE id/*tf_identifier*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: nettype with"); } + { $$ = GRAMMARP->createNettype($6, *$6); BBUNSUP($1, "Unsupported: nettype with"); } ; implicit_typeE: // IEEE: part of *data_type_or_implicit From 4a88ddc616f3613b448b53f10b92961c8badd561 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 17:22:16 -0500 Subject: [PATCH 038/171] Tests: Fix interface syntax error --- test_regress/t/t_mod_interface_array3.out | 2 +- test_regress/t/t_mod_interface_array3.v | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test_regress/t/t_mod_interface_array3.out b/test_regress/t/t_mod_interface_array3.out index 2e9aaf9d7..a2b8ecba7 100644 --- a/test_regress/t/t_mod_interface_array3.out +++ b/test_regress/t/t_mod_interface_array3.out @@ -1,5 +1,5 @@ %Error-UNSUPPORTED: t/t_mod_interface_array3.v:22:20: Unsupported: Multidimensional instances/interfaces. - 22 | a_if iface [2:0][1:0]; + 22 | a_if iface [2:0][1:0] (); | ^ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error-UNSUPPORTED: t/t_mod_interface_array3.v:24:18: Unsupported: Multidimensional instances/interfaces. diff --git a/test_regress/t/t_mod_interface_array3.v b/test_regress/t/t_mod_interface_array3.v index 7ea8a209e..3a83a9ce4 100644 --- a/test_regress/t/t_mod_interface_array3.v +++ b/test_regress/t/t_mod_interface_array3.v @@ -19,7 +19,7 @@ module t; string str [2:0][1:0]; - a_if iface [2:0][1:0]; + a_if iface [2:0][1:0] (); sub i_sub[2:0][1:0] (.s(str)); From 2f4d1647f04e345b028b55d424c343cd1272ae1e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 20:20:54 -0500 Subject: [PATCH 039/171] Fix non-interface error message --- src/V3AstNodeDType.h | 1 + src/V3LinkCells.cpp | 2 +- test_regress/t/t_interface_paren_missing_bad.v | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 3dc9d7d2c..18d121cb7 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -904,6 +904,7 @@ public: string cellName() const { return m_cellName; } void cellName(const string& name) { m_cellName = name; } string ifaceName() const { return m_ifaceName; } + string ifaceNameQ() const { return "'" + prettyName(ifaceName()) + "'"; } void ifaceName(const string& name) { m_ifaceName = name; } string modportName() const { return m_modportName; } AstIface* ifaceViaCellp() const; // Use cellp or ifacep diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index c240cf76a..5667f8856 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -236,7 +236,7 @@ class LinkCellsVisitor final : public VNVisitor { if (!nodep->cellp()) nodep->ifacep(VN_AS(modp, Iface)); } else if (VN_IS(modp, NotFoundModule)) { // Will error out later } else { - nodep->v3error("Non-interface used as an interface: " << nodep->prettyNameQ()); + nodep->v3error("Non-interface used as an interface: " << nodep->ifaceNameQ()); } } iterateChildren(nodep); diff --git a/test_regress/t/t_interface_paren_missing_bad.v b/test_regress/t/t_interface_paren_missing_bad.v index c1a9edae4..5a02d2ae1 100644 --- a/test_regress/t/t_interface_paren_missing_bad.v +++ b/test_regress/t/t_interface_paren_missing_bad.v @@ -1,11 +1,11 @@ // DESCRIPTION: Verilator: Verilog Test module // -// Interface instantiation without paranthesis -// // This file ONLY is placed under the Creative Commons Public Domain, for // any use, without warranty, 2023 by Goekce Aydos. // SPDX-License-Identifier: CC0-1.0 +// Interface instantiation without parenthesis + interface intf; endinterface From b741105329ae156e0acf947cf62ea6bc738dab42 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 20:47:59 -0500 Subject: [PATCH 040/171] Tests: Fix t_dist_whitespace error message --- test_regress/t/t_dist_whitespace.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test_regress/t/t_dist_whitespace.py b/test_regress/t/t_dist_whitespace.py index 1c9da5b27..3a6ae33be 100755 --- a/test_regress/t/t_dist_whitespace.py +++ b/test_regress/t/t_dist_whitespace.py @@ -103,13 +103,14 @@ if fcount < 50: if len(warns): # First warning lists everything as that's shown in the driver summary + msg = "" if 'HARNESS_UPDATE_GOLDEN' in os.environ: - test.error("Updated files with whitespace errors: " + ' '.join(sorted(warns.keys()))) - test.error("To auto-fix: HARNESS_UPDATE_GOLDEN=1 {command} or --golden") + msg += "Updated files with whitespace errors: " + ' '.join(sorted(warns.keys())) + "\n" else: - test.error("Files have whitespace errors: " + ' '.join(sorted(warns.keys()))) - test.error("To auto-fix: HARNESS_UPDATE_GOLDEN=1 {command} or --golden") + msg += "Files have whitespace errors: " + ' '.join(sorted(warns.keys())) + "\n" + msg += "To auto-fix: HARNESS_UPDATE_GOLDEN=1 {command} or --golden\n" for filename in sorted(warns.keys()): - test.error(warns[filename]) + msg += warns[filename] + "\n" + test.error(msg) test.passes() From 0e11b0929c67a59916d5cfa6b7e477d14659e0ec Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 21:33:22 -0500 Subject: [PATCH 041/171] Internals: whitespace --- src/verilog.y | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index acee2bb3b..87c964bc4 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2080,10 +2080,14 @@ tf_port_declaration: // ==IEEE: tf_port_declaration // // Used inside function; followed by ';' // // SEE ALSO port_declaration, port, data_declarationVarFront // - port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } - | port_directionReset implicit_typeE { VARDTYPE_NDECL($2); } list_of_tf_variable_identifiers ';' { $$ = $4; } - | port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } - | port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';' { $$ = $5; } + port_directionReset data_type { VARDTYPE($2); } list_of_tf_variable_identifiers ';' + { $$ = $4; } + | port_directionReset implicit_typeE { VARDTYPE_NDECL($2); } list_of_tf_variable_identifiers ';' + { $$ = $4; } + | port_directionReset yVAR data_type { VARDTYPE($3); } list_of_tf_variable_identifiers ';' + { $$ = $5; } + | port_directionReset yVAR implicit_typeE { VARDTYPE($3); } list_of_tf_variable_identifiers ';' + { $$ = $5; } ; integer_atom_type: // ==IEEE: integer_atom_type @@ -2766,11 +2770,9 @@ always_construct: // IEEE: == always_construct continuous_assign: // IEEE: continuous_assign yASSIGN driveStrengthE delay_controlE assignList ';' - { - $$ = $4; - STRENGTH_LIST($4, $2, AssignW); - DELAY_LIST($3, $4); - } + { $$ = $4; + STRENGTH_LIST($4, $2, AssignW); + DELAY_LIST($3, $4); } ; initial_construct: // IEEE: initial_construct @@ -6039,11 +6041,11 @@ clocking_skew: // IEEE: clocking_skew cycle_delay: // IEEE: cycle_delay yP_POUNDPOUND yaINTNUM - { $$ = new AstDelay{$1, new AstConst{$2, *$2}, true}; } + { $$ = new AstDelay{$1, new AstConst{$2, *$2}, true}; } | yP_POUNDPOUND idAny - { $$ = new AstDelay{$1, new AstParseRef{$2, VParseRefExp::PX_TEXT, *$2, nullptr, nullptr}, true}; } + { $$ = new AstDelay{$1, new AstParseRef{$2, VParseRefExp::PX_TEXT, *$2, nullptr, nullptr}, true}; } | yP_POUNDPOUND '(' expr ')' - { $$ = new AstDelay{$1, $3, true}; } + { $$ = new AstDelay{$1, $3, true}; } ; //************************************************ @@ -6172,9 +6174,9 @@ property_declarationFront: // IEEE: part of property_declaration ; property_port_listE: // IEEE: [ ( [ property_port_list ] ) ] - /* empty */ { $$ = nullptr; } - | '(' ')' { $$ = nullptr; } - | '(' property_port_list ')' { $$ = $2; } + /* empty */ { $$ = nullptr; } + | '(' ')' { $$ = nullptr; } + | '(' property_port_list ')' { $$ = $2; } ; property_port_list: // ==IEEE: property_port_list @@ -6225,8 +6227,8 @@ property_declarationBody: // IEEE: part of property_declaration //UNSUP assertion_variable_declarationList property_statement_spec {} // // IEEE-2012: Incorrectly has yCOVER ySEQUENCE then property_spec here. // // Fixed in IEEE 1800-2017 - property_spec { $$ = $1; } - | property_spec ';' { $$ = $1; } + property_spec { $$ = $1; } + | property_spec ';' { $$ = $1; } ; assertion_variable_declarationList: // IEEE: part of assertion_variable_declaration @@ -6968,7 +6970,7 @@ rs_prodList: // IEEE: rs_prod+ ; rs_prod: // ==IEEE: rs_prod - rs_production_item { $$ = $1; } + rs_production_item { $$ = $1; } | rs_code_block { $$ = $1; } // // IEEE: rs_if_else | yIF '(' expr ')' rs_production_item %prec prLOWER_THAN_ELSE @@ -7162,17 +7164,17 @@ classImplementsE: // IEEE: part of class_declaration // // All 1800-2012 /* empty */ { $$ = nullptr; $$ = nullptr; } | yIMPLEMENTS - /*mid*/ { GRAMMARP->m_inImplements = true; $$ = nullptr; } + /*mid*/ { GRAMMARP->m_inImplements = true; $$ = nullptr; } /*cont*/ classImplementsList - { $$ = $3; $$ = $3; - GRAMMARP->m_inImplements = false; } + { $$ = $3; $$ = $3; + GRAMMARP->m_inImplements = false; } ; classImplementsList: // IEEE: part of class_declaration // // All 1800-2012 classExtendsOne { $$ = $1; $$ = $1; } | classImplementsList ',' classExtendsOne - { $$ = addNextNull($1, $3); $$ = $3; } + { $$ = addNextNull($1, $3); $$ = $3; } ; class_typeExtImpList: // IEEE: class_type: "[package_scope] id [ parameter_value_assignment ]" From bc87270ca9c784c09b8453a8ae969c65a98710b8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 9 Nov 2024 22:26:59 -0500 Subject: [PATCH 042/171] Add UNSUPPORTED on property variable, instead of syntax error. --- src/verilog.y | 5 +++-- test_regress/t/t_assert_property_var_unsup.out | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 87c964bc4..1638c83fa 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6224,10 +6224,11 @@ property_port_itemDirE: ; property_declarationBody: // IEEE: part of property_declaration - //UNSUP assertion_variable_declarationList property_statement_spec {} + assertion_variable_declarationList + { $$ = nullptr; BBUNSUP($1->fileline(), "Unsupported: property variable declaration"); } // // IEEE-2012: Incorrectly has yCOVER ySEQUENCE then property_spec here. // // Fixed in IEEE 1800-2017 - property_spec { $$ = $1; } + | property_spec { $$ = $1; } | property_spec ';' { $$ = $1; } ; diff --git a/test_regress/t/t_assert_property_var_unsup.out b/test_regress/t/t_assert_property_var_unsup.out index ad85bd9df..16e308717 100644 --- a/test_regress/t/t_assert_property_var_unsup.out +++ b/test_regress/t/t_assert_property_var_unsup.out @@ -1,10 +1,14 @@ -%Error: t/t_assert_property_var_unsup.v:17:11: syntax error, unexpected IDENTIFIER, expecting "'{" +%Error-UNSUPPORTED: t/t_assert_property_var_unsup.v:17:11: Unsupported: property variable declaration 17 | int prevcyc; | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: t/t_assert_property_var_unsup.v:18:7: syntax error, unexpected '(', expecting endproperty + 18 | (valid, prevcyc = cyc) |=> (cyc == prevcyc + 1); + | ^ %Error-UNSUPPORTED: t/t_assert_property_var_unsup.v:24:31: Unsupported: property variable default value 24 | property with_def(int nine = 9); | ^ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error: Internal Error: t/t_assert_property_var_unsup.v:7:8: ../V3ParseSym.h:#: Symbols suggest ending PROPERTY 'prop' but parser thinks ending MODULE 't' 7 | module t ( | ^ + ... See the manual at https://verilator.org/verilator_doc.html for more assistance. From 0ec025c40cf35a9fbf648e91f562ce31512ce1fa Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 10:14:42 -0500 Subject: [PATCH 043/171] Internals: Rename rule. No functional change. --- src/verilog.y | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/verilog.y b/src/verilog.y index 1638c83fa..c91609894 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3705,7 +3705,7 @@ statement_item: // IEEE: statement_item | yDISABLE yFORK ';' { $$ = new AstDisableFork{$1}; } | yDISABLE idAny/*UNSUP: hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable{$1, *$2}; } - | yDISABLE idAny '.' idDotted ';' + | yDISABLE idAny '.' idDottedSel ';' { $$ = nullptr; BBUNSUP($4, "Unsupported: disable with '.'"); } // // IEEE: event_trigger | yP_MINUSGT expr ';' @@ -4141,7 +4141,7 @@ funcRef: // IEEE: part of tf_call | packageClassScope id '(' list_of_argumentsE ')' { $$ = AstDot::newIfPkg($2, $1, new AstFuncRef{$2, *$2, $4}); } //UNSUP list_of_argumentE should be pev_list_of_argumentE - //UNSUP: idDotted is really just id to allow dotted method calls + //UNSUP: idDottedSel is really just id to allow dotted method calls ; task_subroutine_callNoSemi: // similar to IEEE task_subroutine_call but without ';' @@ -4194,7 +4194,7 @@ system_t_call: // IEEE: system_tf_call (as task) refp->pli(true); $$ = refp->makeStmt(); } // - | yD_DUMPPORTS '(' idDotted ',' expr ')' { $$ = new AstDumpCtl{$1, VDumpCtlType::FILE, $5}; DEL($3); + | yD_DUMPPORTS '(' idDottedSel ',' expr ')' { $$ = new AstDumpCtl{$1, VDumpCtlType::FILE, $5}; DEL($3); $$->addNext(new AstDumpCtl{$1, VDumpCtlType::VARS, new AstConst{$1, 1}}); } | yD_DUMPPORTS '(' ',' expr ')' { $$ = new AstDumpCtl{$1, VDumpCtlType::FILE, $4}; @@ -5834,15 +5834,15 @@ variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variab // VarRef to dotted, and/or arrayed, and/or bit-ranged variable idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable - idDotted { $$ = $1; } + idDottedSel { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select - | yTHIS '.' idDotted + | yTHIS '.' idDottedSel { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "this"}, $3}; } - | ySUPER '.' idDotted + | ySUPER '.' idDottedSel { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "super"}, $3}; } - | yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); } - // // Expanded: package_scope idDotted - | packageClassScope idDotted { $$ = new AstDot{$2, true, $1, $2}; } + | yTHIS '.' ySUPER '.' idDottedSel { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); } + // // Expanded: package_scope idDottedSel + | packageClassScope idDottedSel { $$ = new AstDot{$2, true, $1, $2}; } ; idClassSelForeach: @@ -5857,10 +5857,10 @@ idClassSelForeach: | packageClassScope idDottedForeach { $$ = new AstDot{$2, true, $1, $2}; } ; -idDotted: - yD_ROOT '.' idDottedMore +idDottedSel: + yD_ROOT '.' idDottedSelMore { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "$root"}, $3}; } - | idDottedMore { $$ = $1; } + | idDottedSelMore { $$ = $1; } ; idDottedForeach: @@ -5869,9 +5869,9 @@ idDottedForeach: | idDottedMoreForeach { $$ = $1; } ; -idDottedMore: +idDottedSelMore: idArrayed { $$ = $1; } - | idDottedMore '.' idArrayed { $$ = new AstDot{$2, false, $1, $3}; } + | idDottedSelMore '.' idArrayed { $$ = new AstDot{$2, false, $1, $3}; } ; idDottedMoreForeach: From 7f1aae640f10394916945bceb3d8b539acea7ba0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 10:23:29 -0500 Subject: [PATCH 044/171] Fix dotted reference in delay value (#2410). --- Changes | 1 + src/verilog.y | 30 ++++++++++++++--- test_regress/t/t_delay.v | 2 ++ test_regress/t/t_delay_stmtdly_bad.out | 46 +++++++++++++++----------- 4 files changed, 56 insertions(+), 23 deletions(-) diff --git a/Changes b/Changes index acf36fcbd..a5effd1d4 100644 --- a/Changes +++ b/Changes @@ -21,6 +21,7 @@ Verilator 5.031 devel * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add error on `solve before` or soft constraints of `randc` variable. +* Fix dotted reference in delay value (#2410). * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/verilog.y b/src/verilog.y index c91609894..17e484999 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -3075,7 +3075,7 @@ delay_control: //== IEEE: delay_control delay_value: // ==IEEE:delay_value // // IEEE: ps_identifier - packageClassScopeE varRefBase { $$ = AstDot::newIfPkg($2, $1, $2); } + idClass { $$ = $1; } | yaINTNUM { $$ = new AstConst{$1, *$1}; } | yaFLOATNUM { $$ = new AstConst{$1, AstConst::RealDouble{}, $1}; } | timeNumAdjusted { $$ = $1; } @@ -5810,7 +5810,7 @@ idSVKwd: // Warn about non-forward compatible Verilog 200 { static string s = "final"; $$ = &s; ERRSVKWD($1, *$$); $$ = $1; } ; -variable_lvalue: // IEEE: variable_lvalue or net_lvalue +variable_lvalue: // IEEE: variable_lvalue or net_lvalue // // Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist idClassSel { $$ = $1; } | '{' variable_lvalueConcList '}' { $$ = $2; } @@ -5832,8 +5832,19 @@ variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variab //UNSUP | variable_lvalueList ',' variable_lvalue { $$ = addNextNull($1, $3); } //UNSUP ; -// VarRef to dotted, and/or arrayed, and/or bit-ranged variable -idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable +idClass: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable + idDotted { $$ = $1; } + // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select + | yTHIS '.' idDotted + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "this"}, $3}; } + | ySUPER '.' idDotted + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "super"}, $3}; } + | yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); } + // // Expanded: package_scope idDottedSel + | packageClassScope idDotted { $$ = new AstDot{$2, true, $1, $2}; } + ; + +idClassSel: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable idDottedSel { $$ = $1; } // // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select | yTHIS '.' idDottedSel @@ -5857,6 +5868,12 @@ idClassSelForeach: | packageClassScope idDottedForeach { $$ = new AstDot{$2, true, $1, $2}; } ; +idDotted: + yD_ROOT '.' idDottedMore + { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "$root"}, $3}; } + | idDottedMore { $$ = $1; } + ; + idDottedSel: yD_ROOT '.' idDottedSelMore { $$ = new AstDot{$2, false, new AstParseRef{$1, VParseRefExp::PX_ROOT, "$root"}, $3}; } @@ -5869,6 +5886,11 @@ idDottedForeach: | idDottedMoreForeach { $$ = $1; } ; +idDottedMore: + varRefBase { $$ = $1; } + | idDottedMore '.' varRefBase { $$ = new AstDot{$2, false, $1, $3}; } + ; + idDottedSelMore: idArrayed { $$ = $1; } | idDottedSelMore '.' idArrayed { $$ = new AstDot{$2, false, $1, $3}; } diff --git a/test_regress/t/t_delay.v b/test_regress/t/t_delay.v index 4b01e9eb8..e541a10d0 100644 --- a/test_regress/t/t_delay.v +++ b/test_regress/t/t_delay.v @@ -18,12 +18,14 @@ module t (/*AUTOARG*/ wire [31:0] dly1; wire [31:0] dly2 = dly1 + 32'h1; wire [31:0] dly3; + wire [31:0] dly4; typedef struct packed { int dly; } dly_s_t; dly_s_t dly_s; assign #(1.2000000000000000) dly1 = dly0 + 32'h1; assign #(sub.delay) dly3 = dly1 + 1; + assign #sub.delay dly4 = dly1 + 1; sub sub(); diff --git a/test_regress/t/t_delay_stmtdly_bad.out b/test_regress/t/t_delay_stmtdly_bad.out index 40b0b31a3..441588a9c 100644 --- a/test_regress/t/t_delay_stmtdly_bad.out +++ b/test_regress/t/t_delay_stmtdly_bad.out @@ -1,39 +1,47 @@ -%Warning-ASSIGNDLY: t/t_delay.v:25:11: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:26:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 25 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1; + 26 | assign #(1.2000000000000000) dly1 = dly0 + 32'h1; | ^ ... For warning description see https://verilator.org/warn/ASSIGNDLY?v=latest ... Use "/* verilator lint_off ASSIGNDLY */" and lint_on around source to disable this message. -%Warning-ASSIGNDLY: t/t_delay.v:26:11: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:27:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 26 | assign #(sub.delay) dly3 = dly1 + 1; + 27 | assign #(sub.delay) dly3 = dly1 + 1; | ^ -%Warning-ASSIGNDLY: t/t_delay.v:33:18: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:28:11: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 33 | dly0 <= #0 32'h11; - | ^ -%Warning-ASSIGNDLY: t/t_delay.v:36:18: Ignoring timing control on this assignment/primitive due to --no-timing + 28 | assign #sub.delay dly4 = dly1 + 1; + | ^ +%Warning-ASSIGNDLY: t/t_delay.v:35:18: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 36 | dly0 <= #0.12 dly0 + 32'h12; + 35 | dly0 <= #0 32'h11; | ^ -%Warning-ASSIGNDLY: t/t_delay.v:44:18: Ignoring timing control on this assignment/primitive due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:38:18: Ignoring timing control on this assignment/primitive due to --no-timing : ... note: In instance 't' - 44 | dly0 <= #(dly_s.dly) 32'h55; + 38 | dly0 <= #0.12 dly0 + 32'h12; | ^ -%Warning-STMTDLY: t/t_delay.v:50:10: Ignoring delay on this statement due to --no-timing +%Warning-ASSIGNDLY: t/t_delay.v:46:18: Ignoring timing control on this assignment/primitive due to --no-timing + : ... note: In instance 't' + 46 | dly0 <= #(dly_s.dly) 32'h55; + | ^ +%Warning-STMTDLY: t/t_delay.v:52:10: Ignoring delay on this statement due to --no-timing : ... note: In instance 't' - 50 | #100 $finish; + 52 | #100 $finish; | ^ -%Warning-UNUSEDSIGNAL: t/t_delay.v:23:12: Signal is not used: 'dly_s' +%Warning-UNUSEDSIGNAL: t/t_delay.v:21:16: Signal is not used: 'dly4' : ... note: In instance 't' - 23 | dly_s_t dly_s; + 21 | wire [31:0] dly4; + | ^~~~ +%Warning-UNUSEDSIGNAL: t/t_delay.v:24:12: Signal is not used: 'dly_s' + : ... note: In instance 't' + 24 | dly_s_t dly_s; | ^~~~~ -%Warning-UNUSEDSIGNAL: t/t_delay.v:57:13: Signal is not used: 'delay' +%Warning-UNUSEDSIGNAL: t/t_delay.v:59:13: Signal is not used: 'delay' : ... note: In instance 't.sub' - 57 | realtime delay = 2.3; + 59 | realtime delay = 2.3; | ^~~~~ -%Warning-BLKSEQ: t/t_delay.v:43:20: Blocking assignment '=' in sequential logic process +%Warning-BLKSEQ: t/t_delay.v:45:20: Blocking assignment '=' in sequential logic process : ... Suggest using delayed assignment '<=' - 43 | dly_s.dly = 55; + 45 | dly_s.dly = 55; | ^ %Error: Exiting due to From 77ef2cd487369128521caa432e05e7a361b4d3bb Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 10 Nov 2024 15:51:59 +0000 Subject: [PATCH 045/171] Split up assignments to wides with Concat on the RHS (#5599) Add a new pass to split up (recursively): foo = {l, r}; into the following, with the right indices, iff the concatenation straddles a wide word boundary. foo[_:_] = r; foo[_:_] = l; This eliminates more wide temporaries. Another 23% speedup on VeeR EH2 high_perf. Also brings the predicted stack size from 8M to 40k. --- docs/guide/exe_verilator.rst | 4 + src/CMakeLists.txt | 2 + src/Makefile_obj.in | 1 + src/V3FuncOpt.cpp | 182 ++++++++++++++++++++ src/V3FuncOpt.h | 32 ++++ src/V3Options.cpp | 4 + src/V3Options.h | 3 + src/Verilator.cpp | 4 + test_regress/t/t_dfg_balance_cats.py | 3 + test_regress/t/t_dfg_balance_cats_nofunc.py | 26 +++ 10 files changed, 261 insertions(+) create mode 100644 src/V3FuncOpt.cpp create mode 100644 src/V3FuncOpt.h create mode 100755 test_regress/t/t_dfg_balance_cats_nofunc.py diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 0ffe5afb3..e70f70b71 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -589,6 +589,10 @@ Summary: .. option:: -fno-expand +.. option:: -fno-func-opt + +.. option:: -fno-func-opt-split-cat + .. option:: -fno-gate .. option:: -fno-inline diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9049fc215..9b1aac1d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -95,6 +95,7 @@ set(HEADERS V3Force.h V3Fork.h V3FunctionTraits.h + V3FuncOpt.h V3Gate.h V3Global.h V3Graph.h @@ -255,6 +256,7 @@ set(COMMON_SOURCES V3FileLine.cpp V3Force.cpp V3Fork.cpp + V3FuncOpt.cpp V3Gate.cpp V3Global.cpp V3Graph.cpp diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 0e972fc71..0945e4690 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -204,6 +204,7 @@ RAW_OBJS_PCH_ASTMT = \ V3EmitCPch.o \ V3EmitV.o \ V3File.o \ + V3FuncOpt.o \ V3Global.o \ V3Hasher.o \ V3Number.o \ diff --git a/src/V3FuncOpt.cpp b/src/V3FuncOpt.cpp new file mode 100644 index 000000000..f71621a24 --- /dev/null +++ b/src/V3FuncOpt.cpp @@ -0,0 +1,182 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Generic optimizations on a per function basis +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2024 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 +// +//************************************************************************* +// +// - Split assignments to wide locations with Concat on the RHS +// at word boundaries: +// foo = {l, r}; +// becomes (recursively): +// foo[_:_] = r; +// foo[_:_] = l; +// +//************************************************************************* + +#include "V3PchAstMT.h" + +#include "V3FuncOpt.h" + +#include "V3Global.h" +#include "V3Stats.h" +#include "V3ThreadPool.h" + +VL_DEFINE_DEBUG_FUNCTIONS; + +class FuncOptVisitor final : public VNVisitor { + // NODE STATE + // AstNodeAssign::user() -> bool. Already checked, safe to split. Omit expensive check. + + // STATE - Statistic tracking + VDouble0 m_concatSplits; // Number of splits in assignments with Concat on RHS + + // True for e.g.: foo = foo >> 1; or foo[foo[0]] = ...; + static bool readsLhs(AstNodeAssign* nodep) { + // It is expected that the number of vars written on the LHS is very small (should be 1). + std::unordered_set lhsWrVarps; + std::unordered_set lhsRdVarps; + nodep->lhsp()->foreach([&](const AstVarRef* refp) { + if (refp->access().isWriteOrRW()) lhsWrVarps.emplace(refp->varp()); + if (refp->access().isReadOrRW()) lhsRdVarps.emplace(refp->varp()); + }); + + // Common case of 1 variable on the LHS - special handling for speed + if (lhsWrVarps.size() == 1) { + const AstVar* const lhsWrVarp = *lhsWrVarps.begin(); + // Check Rhs doesn't read the written var + const bool rhsReadsWritten = nodep->rhsp()->exists([=](const AstVarRef* refp) { // + return refp->varp() == lhsWrVarp; + }); + if (rhsReadsWritten) return true; + // Check Lhs doesn't read the written var + return lhsRdVarps.count(lhsWrVarp); + } + + // Generic case of multiple vars written on LHS + // TODO: this might be impossible due to earlier transforms, not sure + // Check Rhs doesn't read the written vars + const bool rhsReadsWritten = nodep->rhsp()->exists([&](const AstVarRef* refp) { // + return lhsWrVarps.count(refp->varp()); + }); + if (rhsReadsWritten) return true; + // Check Lhs doesn't read the written vars + for (const AstVar* const lhsWrVarp : lhsWrVarps) { + if (lhsRdVarps.count(lhsWrVarp)) return true; + } + return false; + } + + // METHODS + // Split wide assignments with a wide concatenation on the RHS. + // Returns true if 'nodep' was deleted + bool splitConcat(AstNodeAssign* nodep) { + UINFO(9, "splitConcat " << nodep << "\n"); + // Only care about concatenations on the right + AstConcat* const rhsp = VN_CAST(nodep->rhsp(), Concat); + if (!rhsp) return false; + // Will need the LHS + AstNodeExpr* lhsp = nodep->lhsp(); + UASSERT_OBJ(lhsp->width() == rhsp->width(), nodep, "Inconsistent assignment"); + // Only consider pure assignments. Nodes inserted below are safe. + if (!nodep->user1() && (!lhsp->isPure() || !rhsp->isPure())) return false; + // Check for a Sel on the LHS if present, and skip over it + uint32_t lsb = 0; + if (AstSel* const selp = VN_CAST(lhsp, Sel)) { + if (AstConst* const lsbp = VN_CAST(selp->lsbp(), Const)) { + lhsp = selp->fromp(); + lsb = lsbp->toUInt(); + } else { + // Don't optimize if it's a variable select + return false; + } + } + // No need to split assignments targeting storage smaller than a machine register + if (lhsp->width() <= VL_QUADSIZE) return false; + + // If it's a concat straddling a word boundary, try to split it. + // The next visit on the new nodes will split it recursively. + // Otherwise, keep the original assignment. + const int lsbWord = lsb / VL_EDATASIZE; + const int msbWord = (lsb + rhsp->width() - 1) / VL_EDATASIZE; + if (lsbWord == msbWord) return false; + + // If the RHS reads the LHS, we can't actually do this. Nodes inserted below are safe. + if (!nodep->user1() && readsLhs(nodep)) return false; + + // Ok, actually split it now + UINFO(5, "splitConcat optimizing " << nodep << "\n"); + ++m_concatSplits; + // The 2 parts and their offsets + AstNodeExpr* const rrp = rhsp->rhsp()->unlinkFrBack(); + AstNodeExpr* const rlp = rhsp->lhsp()->unlinkFrBack(); + const int rLsb = lsb; + const int lLsb = lsb + rrp->width(); + // Insert the 2 assignment right after the original. They will be visited next. + AstAssign* const arp = new AstAssign{ + nodep->fileline(), + new AstSel{lhsp->fileline(), lhsp->cloneTreePure(false), rLsb, rrp->width()}, rrp}; + AstAssign* const alp = new AstAssign{ + nodep->fileline(), + new AstSel{lhsp->fileline(), lhsp->unlinkFrBack(), lLsb, rlp->width()}, rlp}; + nodep->addNextHere(arp); + arp->addNextHere(alp); + // Safe to split these. + arp->user1(true); + alp->user1(true); + // Nuke what is left + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + return true; + } + + // VISIT + void visit(AstNodeAssign* nodep) override { + // TODO: Only thing remaining inside functions should be AstAssign (that is, an actual + // assignment statemant), but we stil use AstAssignW, AstAssignDly, and all, fix. + if (v3Global.opt.fFuncSplitCat()) { + if (splitConcat(nodep)) return; // Must return here, in case more code is added below + } + } + + void visit(AstNodeExpr*) override {} // No need to descend further (Ignore AstExprStmt...) + + void visit(AstNode* nodep) override { iterateChildren(nodep); } + + // CONSTRUCTORS + explicit FuncOptVisitor(AstCFunc* funcp) { iterateChildren(funcp); } + ~FuncOptVisitor() override { + V3Stats::addStatSum("Optimizations, FuncOpt concat splits", m_concatSplits); + } + +public: + static void apply(AstCFunc* funcp) { FuncOptVisitor{funcp}; } +}; + +//###################################################################### + +void V3FuncOpt::funcOptAll(AstNetlist* nodep) { + UINFO(2, __FUNCTION__ << ": " << endl); + { + const VNUser1InUse user1InUse; + V3ThreadScope threadScope; + for (AstNodeModule *modp = nodep->modulesp(), *nextModp; modp; modp = nextModp) { + nextModp = VN_AS(modp->nextp(), NodeModule); + for (AstNode *nodep = modp->stmtsp(), *nextNodep; nodep; nodep = nextNodep) { + nextNodep = nodep->nextp(); + if (AstCFunc* const cfuncp = VN_CAST(nodep, CFunc)) { + threadScope.enqueue([cfuncp]() { FuncOptVisitor::apply(cfuncp); }); + } + } + } + } + V3Global::dumpCheckGlobalTree("funcopt", 0, dumpTreeEitherLevel() >= 3); +} diff --git a/src/V3FuncOpt.h b/src/V3FuncOpt.h new file mode 100644 index 000000000..d6c1de2d3 --- /dev/null +++ b/src/V3FuncOpt.h @@ -0,0 +1,32 @@ +// -*- mode: C++; c-file-style: "cc-mode" -*- +//************************************************************************* +// DESCRIPTION: Verilator: Generic optimizations on a per function basis +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2003-2024 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 +// +//************************************************************************* + +#ifndef VERILATOR_V3FUNCOPT_H_ +#define VERILATOR_V3FUNCOPT_H_ + +#include "config_build.h" +#include "verilatedos.h" + +class AstNetlist; + +//============================================================================ + +class V3FuncOpt final { +public: + static void funcOptAll(AstNetlist* nodep); +}; + +#endif // Guard diff --git a/src/V3Options.cpp b/src/V3Options.cpp index ae32fdf3d..11a154a43 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1303,6 +1303,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-fdead-assigns", FOnOff, &m_fDeadAssigns); DECL_OPTION("-fdead-cells", FOnOff, &m_fDeadCells); DECL_OPTION("-fexpand", FOnOff, &m_fExpand); + DECL_OPTION("-ffunc-opt", CbFOnOff, [this](bool flag) { // + m_fFuncSplitCat = flag; + }); + DECL_OPTION("-ffunc-opt-split-cat", FOnOff, &m_fFuncSplitCat); DECL_OPTION("-fgate", FOnOff, &m_fGate); DECL_OPTION("-finline", FOnOff, &m_fInline); DECL_OPTION("-flife", FOnOff, &m_fLife); diff --git a/src/V3Options.h b/src/V3Options.h index 2ac99bf04..5eaa0aebd 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -384,6 +384,7 @@ private: bool m_fDeadAssigns; // main switch: -fno-dead-assigns: remove dead assigns bool m_fDeadCells; // main switch: -fno-dead-cells: remove dead cells bool m_fExpand; // main switch: -fno-expand: expansion of C macros + bool m_fFuncSplitCat = true; // main switch: -fno-func-split-cat: expansion of C macros bool m_fGate; // main switch: -fno-gate: gate wire elimination bool m_fInline; // main switch: -fno-inline: module inlining bool m_fLife; // main switch: -fno-life: variable lifetime @@ -674,6 +675,8 @@ public: bool fDeadAssigns() const { return m_fDeadAssigns; } bool fDeadCells() const { return m_fDeadCells; } bool fExpand() const { return m_fExpand; } + bool fFuncSplitCat() const { return m_fFuncSplitCat; } + bool fFunc() const { return fFuncSplitCat(); } bool fGate() const { return m_fGate; } bool fInline() const { return m_fInline; } bool fLife() const { return m_fLife; } diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 92d3f53de..1c4d58cfa 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -53,6 +53,7 @@ #include "V3File.h" #include "V3Force.h" #include "V3Fork.h" +#include "V3FuncOpt.h" #include "V3Gate.h" #include "V3Global.h" #include "V3Graph.h" @@ -497,6 +498,9 @@ static void process() { // --GENERATION------------------ if (!v3Global.opt.serializeOnly()) { + // Generic optimizations on a per-function basis + if (v3Global.opt.fFunc()) V3FuncOpt::funcOptAll(v3Global.rootp()); + // Remove unused vars V3Const::constifyAll(v3Global.rootp()); V3Dead::deadifyAll(v3Global.rootp()); diff --git a/test_regress/t/t_dfg_balance_cats.py b/test_regress/t/t_dfg_balance_cats.py index 0a4055967..93de94adf 100755 --- a/test_regress/t/t_dfg_balance_cats.py +++ b/test_regress/t/t_dfg_balance_cats.py @@ -17,5 +17,8 @@ test.file_grep(test.stats, r' Optimizations, DFG pre inline BalanceTrees, concat trees balanced\s+(\d+)', 0) test.file_grep(test.stats, r' Optimizations, DFG post inline BalanceTrees, concat trees balanced\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, DFG pre inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, DFG post inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, FuncOpt concat splits\s+(\d+)', 62) test.passes() diff --git a/test_regress/t/t_dfg_balance_cats_nofunc.py b/test_regress/t/t_dfg_balance_cats_nofunc.py new file mode 100755 index 000000000..d57622f3a --- /dev/null +++ b/test_regress/t/t_dfg_balance_cats_nofunc.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.top_filename = "t/t_dfg_balance_cats.v" + +test.compile(verilator_flags2=["--stats", "-fno-func-opt"]) + +test.file_grep(test.stats, + r' Optimizations, DFG pre inline BalanceTrees, concat trees balanced\s+(\d+)', 0) +test.file_grep(test.stats, + r' Optimizations, DFG post inline BalanceTrees, concat trees balanced\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, DFG pre inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, DFG post inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep_not(test.stats, r'Optimizations, FuncOpt concat splits') + +test.passes() From a68da7e2205ab77af18479ac1d9be2f665e4b0f9 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 10:51:48 -0500 Subject: [PATCH 046/171] Internals: Style cleanup. Ignore whitespace if diff. No functional change. --- src/V3Assert.cpp | 22 +++---- src/V3Begin.cpp | 93 +++++++++++++++--------------- src/V3Class.cpp | 32 +++++------ src/V3Clean.cpp | 6 +- src/V3Const.cpp | 28 ++++----- src/V3Depth.cpp | 38 ++++++------ src/V3DepthBlock.cpp | 16 ++---- src/V3Descope.cpp | 12 ++-- src/V3EmitCSyms.cpp | 12 ++-- src/V3EmitV.cpp | 12 ++-- src/V3LinkCells.cpp | 10 ++-- src/V3LinkJump.cpp | 30 ++++------ src/V3LinkParse.cpp | 130 ++++++++++++++++++------------------------ src/V3LinkResolve.cpp | 14 ++--- src/V3Reloop.cpp | 8 +-- src/V3Scope.cpp | 52 ++++++++--------- src/V3Table.cpp | 8 +-- src/V3Task.cpp | 40 ++++++------- src/V3Trace.cpp | 6 +- src/V3Undriven.cpp | 48 ++++++---------- src/V3Unknown.cpp | 38 +++++------- src/V3Width.cpp | 32 ++++------- 22 files changed, 285 insertions(+), 402 deletions(-) diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index b90e1e106..8c72aabef 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -510,10 +510,8 @@ class AssertVisitor final : public VNVisitor { // Don't sample sensitivities void visit(AstSenItem* nodep) override { VL_RESTORER(m_inSampled); - { - m_inSampled = false; - iterateChildren(nodep); - } + m_inSampled = false; + iterateChildren(nodep); } //========== Statements @@ -691,12 +689,10 @@ class AssertVisitor final : public VNVisitor { VL_RESTORER(m_modp); VL_RESTORER(m_modPastNum); VL_RESTORER(m_modStrobeNum); - { - m_modp = nodep; - m_modPastNum = 0; - m_modStrobeNum = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_modPastNum = 0; + m_modStrobeNum = 0; + iterateChildren(nodep); } void visit(AstNodeProcedure* nodep) override { VL_RESTORER(m_procedurep); @@ -707,10 +703,8 @@ class AssertVisitor final : public VNVisitor { // This code is needed rather than a visitor in V3Begin, // because V3Assert is called before V3Begin VL_RESTORER(m_beginp); - { - m_beginp = nodep; - iterateChildren(nodep); - } + m_beginp = nodep; + iterateChildren(nodep); } void visit(AstNode* nodep) override { iterateChildren(nodep); } diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index d6e881f40..f20ba4f6d 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -54,8 +54,10 @@ public: //###################################################################### class BeginVisitor final : public VNVisitor { - // STATE + // STATE - across all visitors BeginState* const m_statep; // Current global state + + // STATE - for current visit position (use VL_RESTORER) AstNodeModule* m_modp = nullptr; // Current module AstNodeFTask* m_ftaskp = nullptr; // Current function/task AstNode* m_liftedp = nullptr; // Local nodes we are lifting into m_ftaskp @@ -145,10 +147,8 @@ class BeginVisitor final : public VNVisitor { } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); - { - m_modp = nodep; - iterateChildren(nodep); - } + m_modp = nodep; + iterateChildren(nodep); } void visit(AstNodeFTask* nodep) override { UINFO(8, " " << nodep << endl); @@ -164,29 +164,28 @@ class BeginVisitor final : public VNVisitor { // inside the function. // Process children VL_RESTORER(m_displayScope); + VL_RESTORER(m_ftaskp); + VL_RESTORER(m_liftedp); VL_RESTORER(m_namedScope); VL_RESTORER(m_unnamedScope); - { - m_displayScope = dot(m_displayScope, nodep->name()); - m_namedScope = ""; - m_unnamedScope = ""; - m_ftaskp = nodep; - m_liftedp = nullptr; - iterateChildren(nodep); - nodep->foreach([&](AstInitialStatic* const initp) { - initp->unlinkFrBack(); - m_ftaskp->addHereThisAsNext(initp); - }); - if (m_liftedp) { - // Place lifted nodes at beginning of stmtsp, so Var nodes appear before referenced - if (AstNode* const stmtsp = nodep->stmtsp()) { - stmtsp->unlinkFrBackWithNext(); - m_liftedp->addNext(stmtsp); - } - nodep->addStmtsp(m_liftedp); - m_liftedp = nullptr; + m_displayScope = dot(m_displayScope, nodep->name()); + m_namedScope = ""; + m_unnamedScope = ""; + m_ftaskp = nodep; + m_liftedp = nullptr; + iterateChildren(nodep); + nodep->foreach([&](AstInitialStatic* const initp) { + initp->unlinkFrBack(); + m_ftaskp->addHereThisAsNext(initp); + }); + if (m_liftedp) { + // Place lifted nodes at beginning of stmtsp, so Var nodes appear before referenced + if (AstNode* const stmtsp = nodep->stmtsp()) { + stmtsp->unlinkFrBackWithNext(); + m_liftedp->addNext(stmtsp); } - m_ftaskp = nullptr; + nodep->addStmtsp(m_liftedp); + m_liftedp = nullptr; } } void visit(AstBegin* nodep) override { @@ -196,30 +195,28 @@ class BeginVisitor final : public VNVisitor { VL_RESTORER(m_namedScope); VL_RESTORER(m_unnamedScope); { - { - VL_RESTORER(m_keepBegins); - m_keepBegins = false; - dotNames(nodep, "__BEGIN__"); - } - UASSERT_OBJ(!nodep->genforp(), nodep, "GENFORs should have been expanded earlier"); - - // Cleanup - if (m_keepBegins) { - nodep->name(""); - return; - } - AstNode* addsp = nullptr; - if (AstNode* const stmtsp = nodep->stmtsp()) { - stmtsp->unlinkFrBackWithNext(); - addsp = AstNode::addNext(addsp, stmtsp); - } - if (addsp) { - nodep->replaceWith(addsp); - } else { - nodep->unlinkFrBack(); - } - VL_DO_DANGLING(pushDeletep(nodep), nodep); + VL_RESTORER(m_keepBegins); + m_keepBegins = false; + dotNames(nodep, "__BEGIN__"); } + UASSERT_OBJ(!nodep->genforp(), nodep, "GENFORs should have been expanded earlier"); + + // Cleanup + if (m_keepBegins) { + nodep->name(""); + return; + } + AstNode* addsp = nullptr; + if (AstNode* const stmtsp = nodep->stmtsp()) { + stmtsp->unlinkFrBackWithNext(); + addsp = AstNode::addNext(addsp, stmtsp); + } + if (addsp) { + nodep->replaceWith(addsp); + } else { + nodep->unlinkFrBack(); + } + VL_DO_DANGLING(pushDeletep(nodep), nodep); } void visit(AstVar* nodep) override { // If static variable, move it outside a function. diff --git a/src/V3Class.cpp b/src/V3Class.cpp index 5d187a5c0..9e82be6ea 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -129,24 +129,20 @@ class ClassVisitor final : public VNVisitor { VL_RESTORER(m_classScopep); VL_RESTORER(m_packageScopep); VL_RESTORER(m_modp); - { - m_modp = nodep; - m_classPackagep = packagep; - m_classScopep = classScopep; - m_packageScopep = scopep; - m_prefix = nodep->name() + "__02e"; // . - iterateChildren(nodep); - } + m_modp = nodep; + m_classPackagep = packagep; + m_classScopep = classScopep; + m_packageScopep = scopep; + m_prefix = nodep->name() + "__02e"; // . + iterateChildren(nodep); } void visit(AstNodeModule* nodep) override { // Visit for NodeModules that are not AstClass (AstClass is-a AstNodeModule) VL_RESTORER(m_prefix); VL_RESTORER(m_modp); - { - m_modp = nodep; - m_prefix = nodep->name() + "__03a__03a"; // :: - iterateChildren(nodep); - } + m_modp = nodep; + m_prefix = nodep->name() + "__03a__03a"; // :: + iterateChildren(nodep); } void visit(AstVar* nodep) override { @@ -174,12 +170,10 @@ class ClassVisitor final : public VNVisitor { void visit(AstNodeFTask* nodep) override { VL_RESTORER(m_ftaskp); - { - m_ftaskp = nodep; - iterateChildren(nodep); - if (m_packageScopep && nodep->isStatic()) { - m_toScopeMoves.emplace_back(nodep, m_packageScopep); - } + m_ftaskp = nodep; + iterateChildren(nodep); + if (m_packageScopep && nodep->isStatic()) { + m_toScopeMoves.emplace_back(nodep, m_packageScopep); } } void visit(AstCFunc* nodep) override { diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 9acb79559..90035dc6c 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -173,10 +173,8 @@ class CleanVisitor final : public VNVisitor { // VISITORS void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); - { - m_modp = nodep; - iterateChildren(nodep); - } + m_modp = nodep; + iterateChildren(nodep); } void visit(AstNodeUniop* nodep) override { iterateChildren(nodep); diff --git a/src/V3Const.cpp b/src/V3Const.cpp index dbe81ed4a..ec8107bc6 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -2333,20 +2333,16 @@ class ConstVisitor final : public VNVisitor { } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); - { - m_modp = nodep; - m_concswapNames.reset(); - iterateChildren(nodep); - } + m_modp = nodep; + m_concswapNames.reset(); + iterateChildren(nodep); } void visit(AstCFunc* nodep) override { // No ASSIGNW removals under funcs, we've long eliminated INITIALs // (We should perhaps rename the assignw's to just assigns) VL_RESTORER(m_wremove); - { - m_wremove = false; - iterateChildren(nodep); - } + m_wremove = false; + iterateChildren(nodep); } void visit(AstCLocalScope* nodep) override { iterateChildren(nodep); @@ -2359,11 +2355,9 @@ class ConstVisitor final : public VNVisitor { // No ASSIGNW removals under scope, we've long eliminated INITIALs VL_RESTORER(m_wremove); VL_RESTORER(m_scopep); - { - m_wremove = false; - m_scopep = nodep; - iterateChildren(nodep); - } + m_wremove = false; + m_scopep = nodep; + iterateChildren(nodep); } void swapSides(AstNodeBiCom* nodep) { @@ -2695,10 +2689,8 @@ class ConstVisitor final : public VNVisitor { void visit(AstAttrOf* nodep) override { VL_RESTORER(m_attrp); - { - m_attrp = nodep; - iterateChildren(nodep); - } + m_attrp = nodep; + iterateChildren(nodep); } void visit(AstArraySel* nodep) override { diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index 25a294268..49e386cc5 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -71,35 +71,29 @@ class DepthVisitor final : public VNVisitor { void visit(AstCFunc* nodep) override { VL_RESTORER(m_cfuncp); VL_RESTORER(m_mtaskbodyp); - { - m_cfuncp = nodep; - m_mtaskbodyp = nullptr; - m_depth = 0; - m_maxdepth = 0; - m_tempNames.reset(); - iterateChildren(nodep); - } + m_cfuncp = nodep; + m_mtaskbodyp = nullptr; + m_depth = 0; + m_maxdepth = 0; + m_tempNames.reset(); + iterateChildren(nodep); } void visit(AstMTaskBody* nodep) override { VL_RESTORER(m_cfuncp); VL_RESTORER(m_mtaskbodyp); - { - m_cfuncp = nullptr; - m_mtaskbodyp = nodep; - m_depth = 0; - m_maxdepth = 0; - // We don't reset the names, as must share across tasks - iterateChildren(nodep); - } + m_cfuncp = nullptr; + m_mtaskbodyp = nodep; + m_depth = 0; + m_maxdepth = 0; + // We don't reset the names, as must share across tasks + iterateChildren(nodep); } void visitStmt(AstNodeStmt* nodep) { VL_RESTORER(m_stmtp); - { - m_stmtp = nodep; - m_depth = 0; - m_maxdepth = 0; - iterateChildren(nodep); - } + m_stmtp = nodep; + m_depth = 0; + m_maxdepth = 0; + iterateChildren(nodep); } void visit(AstNodeStmt* nodep) override { visitStmt(nodep); } // Operators diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index 54fa3f2b6..296709bb0 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -70,21 +70,17 @@ class DepthBlockVisitor final : public VNVisitor { void visit(AstNodeModule* nodep) override { UINFO(4, " MOD " << nodep << endl); VL_RESTORER(m_modp); - { - m_modp = nodep; - m_deepNum = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_deepNum = 0; + iterateChildren(nodep); } void visit(AstCFunc* nodep) override { // We recurse into this. VL_RESTORER(m_depth); VL_RESTORER(m_cfuncp); - { - m_depth = 0; - m_cfuncp = nodep; - iterateChildren(nodep); - } + m_depth = 0; + m_cfuncp = nodep; + iterateChildren(nodep); } void visit(AstStmtExpr* nodep) override {} // Stop recursion after introducing new function void visit(AstJumpBlock*) override {} // Stop recursion as can't break up across a jump diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index 42c718c9b..b6ff4c07e 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -208,13 +208,11 @@ class DescopeVisitor final : public VNVisitor { // VISITORS void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); - { - m_modp = nodep; - m_modFuncs.clear(); - m_modSingleton = modIsSingleton(m_modp); - iterateChildren(nodep); - makePublicFuncWrappers(); - } + m_modp = nodep; + m_modFuncs.clear(); + m_modSingleton = modIsSingleton(m_modp); + iterateChildren(nodep); + makePublicFuncWrappers(); } void visit(AstScope* nodep) override { m_scopep = nodep; diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 4198eecc5..e2e020f7f 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -300,10 +300,8 @@ class EmitCSyms final : EmitCBaseVisitorConst { void visit(AstNodeModule* nodep) override { nameCheck(nodep); VL_RESTORER(m_modp); - { - m_modp = nodep; - iterateChildrenConst(nodep); - } + m_modp = nodep; + iterateChildrenConst(nodep); } void visit(AstCellInlineScope* nodep) override { if (v3Global.opt.vpi()) { @@ -372,10 +370,8 @@ class EmitCSyms final : EmitCBaseVisitorConst { nameCheck(nodep); if (nodep->dpiImportPrototype() || nodep->dpiExportDispatcher()) m_dpis.push_back(nodep); VL_RESTORER(m_cfuncp); - { - m_cfuncp = nodep; - iterateChildrenConst(nodep); - } + m_cfuncp = nodep; + iterateChildrenConst(nodep); } //--------------------------------------- diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index c3c9c7d8b..861787ae8 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -393,13 +393,11 @@ class EmitVBaseVisitorConst VL_NOT_FINAL : public EmitCBaseVisitorConst { } void visit(AstTextBlock* nodep) override { visit(static_cast(nodep)); - { - VL_RESTORER(m_suppressSemi); - m_suppressVarSemi = nodep->commas(); - for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) { - iterateConst(childp); - if (nodep->commas() && childp->nextp()) puts(", "); - } + VL_RESTORER(m_suppressSemi); + m_suppressVarSemi = nodep->commas(); + for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) { + iterateConst(childp); + if (nodep->commas() && childp->nextp()) puts(", "); } } void visit(AstScopeName* nodep) override {} diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 5667f8856..5263080b6 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -286,12 +286,10 @@ class LinkCellsVisitor final : public VNVisitor { AstNode* const cellsp = nodep->cellsp()->unlinkFrBackWithNext(); // Module may have already linked, so need to pick up these new cells VL_RESTORER(m_modp); - { - m_modp = modp; - // Important that this adds to end, as next iterate assumes does all cells - modp->addStmtsp(cellsp); - iterateAndNextNull(cellsp); - } + m_modp = modp; + // Important that this adds to end, as next iterate assumes does all cells + modp->addStmtsp(cellsp); + iterateAndNextNull(cellsp); } VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); } diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index 7919b9ecb..693d9da11 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -163,11 +163,9 @@ class LinkJumpVisitor final : public VNVisitor { if (nodep->dead()) return; VL_RESTORER(m_modp); VL_RESTORER(m_modRepeatNum); - { - m_modp = nodep; - m_modRepeatNum = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_modRepeatNum = 0; + iterateChildren(nodep); } void visit(AstNodeFTask* nodep) override { m_ftaskp = nodep; @@ -236,15 +234,13 @@ class LinkJumpVisitor final : public VNVisitor { m_unrollFull = VOptionBool::OPT_DEFAULT_FALSE; VL_RESTORER(m_loopp); VL_RESTORER(m_loopInc); - { - m_loopp = nodep; - m_loopInc = false; - iterateAndNextNull(nodep->precondsp()); - iterateAndNextNull(nodep->condp()); - iterateAndNextNull(nodep->stmtsp()); - m_loopInc = true; - iterateAndNextNull(nodep->incsp()); - } + m_loopp = nodep; + m_loopInc = false; + iterateAndNextNull(nodep->precondsp()); + iterateAndNextNull(nodep->condp()); + iterateAndNextNull(nodep->stmtsp()); + m_loopInc = true; + iterateAndNextNull(nodep->incsp()); } void visit(AstDoWhile* nodep) override { // It is converted to AstWhile in this visit method @@ -272,10 +268,8 @@ class LinkJumpVisitor final : public VNVisitor { } void visit(AstNodeForeach* nodep) override { VL_RESTORER(m_loopp); - { - m_loopp = nodep; - iterateAndNextNull(nodep->stmtsp()); - } + m_loopp = nodep; + iterateAndNextNull(nodep->stmtsp()); } void visit(AstReturn* nodep) override { iterateChildren(nodep); diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 123716fb2..69a5d2c2e 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -101,11 +101,9 @@ class LinkParseVisitor final : public VNVisitor { void visitIterateNodeDType(AstNodeDType* nodep) { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); - { - VL_RESTORER(m_dtypep); - m_dtypep = nodep; - iterateChildren(nodep); - } + VL_RESTORER(m_dtypep); + m_dtypep = nodep; + iterateChildren(nodep); } } @@ -186,58 +184,54 @@ class LinkParseVisitor final : public VNVisitor { cleanFileline(nodep); VL_RESTORER(m_ftaskp); VL_RESTORER(m_lifetime); - { - m_ftaskp = nodep; - if (!nodep->lifetime().isNone()) { - m_lifetime = nodep->lifetime(); - } else { - if (nodep->classMethod()) { - // Class methods are automatic by default - m_lifetime = VLifetime::AUTOMATIC; - } else if (nodep->dpiImport() || VN_IS(nodep, Property)) { - // DPI-imported functions and properties don't have lifetime specifiers - m_lifetime = VLifetime::NONE; - } - for (AstNode* itemp = nodep->stmtsp(); itemp; itemp = itemp->nextp()) { - AstVar* const varp = VN_CAST(itemp, Var); - if (varp && varp->valuep() && varp->lifetime().isNone() - && m_lifetime.isStatic() && !varp->isIO()) { - if (VN_IS(m_modp, Module)) { - nodep->v3warn(IMPLICITSTATIC, - "Function/task's lifetime implicitly set to static\n" - << nodep->warnMore() - << "... Suggest use 'function automatic' or " - "'function static'\n" - << nodep->warnContextPrimary() << '\n' - << varp->warnOther() - << "... Location of implicit static variable\n" - << varp->warnContextSecondary() << '\n' - << "... Suggest use 'function automatic' or " - "'function static'"); - } else { - varp->v3warn(IMPLICITSTATIC, - "Variable's lifetime implicitly set to static\n" - << nodep->warnMore() - << "... Suggest use 'static' before " - "variable declaration'"); - } + m_ftaskp = nodep; + if (!nodep->lifetime().isNone()) { + m_lifetime = nodep->lifetime(); + } else { + if (nodep->classMethod()) { + // Class methods are automatic by default + m_lifetime = VLifetime::AUTOMATIC; + } else if (nodep->dpiImport() || VN_IS(nodep, Property)) { + // DPI-imported functions and properties don't have lifetime specifiers + m_lifetime = VLifetime::NONE; + } + for (AstNode* itemp = nodep->stmtsp(); itemp; itemp = itemp->nextp()) { + AstVar* const varp = VN_CAST(itemp, Var); + if (varp && varp->valuep() && varp->lifetime().isNone() + && m_lifetime.isStatic() && !varp->isIO()) { + if (VN_IS(m_modp, Module)) { + nodep->v3warn(IMPLICITSTATIC, + "Function/task's lifetime implicitly set to static\n" + << nodep->warnMore() + << "... Suggest use 'function automatic' or " + "'function static'\n" + << nodep->warnContextPrimary() << '\n' + << varp->warnOther() + << "... Location of implicit static variable\n" + << varp->warnContextSecondary() << '\n' + << "... Suggest use 'function automatic' or " + "'function static'"); + } else { + varp->v3warn(IMPLICITSTATIC, + "Variable's lifetime implicitly set to static\n" + << nodep->warnMore() + << "... Suggest use 'static' before " + "variable declaration'"); } } - nodep->lifetime(m_lifetime); } - iterateChildren(nodep); + nodep->lifetime(m_lifetime); } + iterateChildren(nodep); } } void visit(AstNodeFTaskRef* nodep) override { if (!nodep->user1SetOnce()) { // Process only once. cleanFileline(nodep); UINFO(5, " " << nodep << endl); - { - VL_RESTORER(m_valueModp); - m_valueModp = nullptr; - iterateChildren(nodep); - } + VL_RESTORER(m_valueModp); + m_valueModp = nullptr; + iterateChildren(nodep); } } void visit(AstNodeDType* nodep) override { visitIterateNodeDType(nodep); } @@ -580,19 +574,15 @@ class LinkParseVisitor final : public VNVisitor { void visit(AstRepeat* nodep) override { cleanFileline(nodep); VL_RESTORER(m_insideLoop); - { - m_insideLoop = true; - checkIndent(nodep, nodep->stmtsp()); - iterateChildren(nodep); - } + m_insideLoop = true; + checkIndent(nodep, nodep->stmtsp()); + iterateChildren(nodep); } void visit(AstDoWhile* nodep) override { cleanFileline(nodep); VL_RESTORER(m_insideLoop); - { - m_insideLoop = true; - iterateChildren(nodep); - } + m_insideLoop = true; + iterateChildren(nodep); } void visit(AstWait* nodep) override { cleanFileline(nodep); @@ -608,11 +598,9 @@ class LinkParseVisitor final : public VNVisitor { void visit(AstWhile* nodep) override { cleanFileline(nodep); VL_RESTORER(m_insideLoop); - { - m_insideLoop = true; - checkIndent(nodep, nodep->stmtsp()); - iterateChildren(nodep); - } + m_insideLoop = true; + checkIndent(nodep, nodep->stmtsp()); + iterateChildren(nodep); } void visit(AstNodeModule* nodep) override { V3Config::applyModule(nodep); @@ -651,11 +639,9 @@ class LinkParseVisitor final : public VNVisitor { void visitIterateNoValueMod(AstNode* nodep) { // Iterate a node which shouldn't have any local variables moved to an Initial cleanFileline(nodep); - { - VL_RESTORER(m_valueModp); - m_valueModp = nullptr; - iterateChildren(nodep); - } + VL_RESTORER(m_valueModp); + m_valueModp = nullptr; + iterateChildren(nodep); } void visit(AstNodeProcedure* nodep) override { visitIterateNoValueMod(nodep); } void visit(AstAlways* nodep) override { @@ -721,13 +707,11 @@ class LinkParseVisitor final : public VNVisitor { void visit(AstGenCase* nodep) override { ++m_genblkNum; cleanFileline(nodep); - { - VL_RESTORER(m_genblkAbove); - VL_RESTORER(m_genblkNum); - m_genblkAbove = m_genblkNum; - m_genblkNum = 0; - iterateChildren(nodep); - } + VL_RESTORER(m_genblkAbove); + VL_RESTORER(m_genblkNum); + m_genblkAbove = m_genblkNum; + m_genblkNum = 0; + iterateChildren(nodep); } void visit(AstGenIf* nodep) override { cleanFileline(nodep); diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 426d7b1ca..58af8051c 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -63,18 +63,14 @@ class LinkResolveVisitor final : public VNVisitor { if (nodep->dead()) return; VL_RESTORER(m_modp); VL_RESTORER(m_senitemCvtNum); - { - m_modp = nodep; - m_senitemCvtNum = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_senitemCvtNum = 0; + iterateChildren(nodep); } void visit(AstClass* nodep) override { VL_RESTORER(m_classp); - { - m_classp = nodep; - iterateChildren(nodep); - } + m_classp = nodep; + iterateChildren(nodep); } void visit(AstInitialAutomatic* nodep) override { iterateChildren(nodep); diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index 15c4afbc7..4d61ba20b 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -145,11 +145,9 @@ class ReloopVisitor final : public VNVisitor { // VISITORS void visit(AstCFunc* nodep) override { VL_RESTORER(m_cfuncp); - { - m_cfuncp = nodep; - iterateChildren(nodep); - mergeEnd(); // Finish last pending merge, if any - } + m_cfuncp = nodep; + iterateChildren(nodep); + mergeEnd(); // Finish last pending merge, if any } void visit(AstNodeAssign* nodep) override { if (!m_cfuncp) return; diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index 81621ca3e..bc71b549a 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -149,32 +149,30 @@ class ScopeVisitor final : public VNVisitor { VL_RESTORER(m_aboveCellp); VL_RESTORER(m_aboveScopep); VL_RESTORER(m_modp); - { - m_aboveScopep = m_scopep; - m_modp = nodep; + m_aboveScopep = m_scopep; + m_modp = nodep; - string scopename; - if (!m_aboveScopep) { - scopename = "TOP"; - } else { - scopename = m_aboveScopep->name() + "." + nodep->name(); - } - - UINFO(4, " CLASS AT " << scopename << " " << nodep << endl); - AstNode::user1ClearTree(); - - const AstNode* const abovep = (m_aboveCellp ? static_cast(m_aboveCellp) - : static_cast(nodep)); - m_scopep - = new AstScope{abovep->fileline(), m_modp, scopename, m_aboveScopep, m_aboveCellp}; - m_packageScopes.emplace(nodep, m_scopep); - - // Create scope for the current usage of this cell - AstNode::user1ClearTree(); - nodep->addMembersp(m_scopep); - - iterateChildren(nodep); + string scopename; + if (!m_aboveScopep) { + scopename = "TOP"; + } else { + scopename = m_aboveScopep->name() + "." + nodep->name(); } + + UINFO(4, " CLASS AT " << scopename << " " << nodep << endl); + AstNode::user1ClearTree(); + + const AstNode* const abovep + = (m_aboveCellp ? static_cast(m_aboveCellp) : static_cast(nodep)); + m_scopep + = new AstScope{abovep->fileline(), m_modp, scopename, m_aboveScopep, m_aboveCellp}; + m_packageScopes.emplace(nodep, m_scopep); + + // Create scope for the current usage of this cell + AstNode::user1ClearTree(); + nodep->addMembersp(m_scopep); + + iterateChildren(nodep); } void visit(AstCellInline* nodep) override { // if (v3Global.opt.vpi()) { @@ -334,10 +332,8 @@ class ScopeCleanupVisitor final : public VNVisitor { void visit(AstScope* nodep) override { // Want to ignore blocks under it VL_RESTORER(m_scopep); - { - m_scopep = nodep; - iterateChildren(nodep); - } + m_scopep = nodep; + iterateChildren(nodep); } virtual void movedDeleteOrIterate(AstNode* nodep) { diff --git a/src/V3Table.cpp b/src/V3Table.cpp index 0c356dd38..a6ac5be24 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -383,11 +383,9 @@ private: void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); VL_RESTORER(m_modTables); - { - m_modp = nodep; - m_modTables = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_modTables = 0; + iterateChildren(nodep); } void visit(AstScope* nodep) override { UINFO(4, " SCOPE " << nodep << endl); diff --git a/src/V3Task.cpp b/src/V3Task.cpp index 460647692..b2603a1cd 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -217,20 +217,18 @@ private: } void visit(AstNodeFTask* nodep) override { UINFO(9, " TASK " << nodep << endl); - { - VL_RESTORER(m_curVxp); - m_curVxp = getFTaskVertex(nodep); - if (nodep->dpiImport()) m_curVxp->noInline(true); - if (nodep->classMethod()) m_curVxp->noInline(true); // Until V3Task supports it - if (nodep->recursive()) m_curVxp->noInline(true); - if (nodep->isConstructor()) { - m_curVxp->noInline(true); - m_ctorp = nodep; - UASSERT_OBJ(m_classp, nodep, "Ctor not under class"); - m_funcToClassMap[nodep] = m_classp; - } - iterateChildren(nodep); + VL_RESTORER(m_curVxp); + m_curVxp = getFTaskVertex(nodep); + if (nodep->dpiImport()) m_curVxp->noInline(true); + if (nodep->classMethod()) m_curVxp->noInline(true); // Until V3Task supports it + if (nodep->recursive()) m_curVxp->noInline(true); + if (nodep->isConstructor()) { + m_curVxp->noInline(true); + m_ctorp = nodep; + UASSERT_OBJ(m_classp, nodep, "Ctor not under class"); + m_funcToClassMap[nodep] = m_classp; } + iterateChildren(nodep); } void visit(AstPragma* nodep) override { if (nodep->pragType() == VPragmaType::NO_INLINE_TASK) { @@ -1393,10 +1391,8 @@ class TaskVisitor final : public VNVisitor { // scope then the caller, so we need to restore state. VL_RESTORER(m_scopep); VL_RESTORER(m_insStmtp); - { - m_scopep = m_statep->getScope(nodep); - iterate(nodep); - } + m_scopep = m_statep->getScope(nodep); + iterate(nodep); } void insertBeforeStmt(AstNode* nodep, AstNode* newp) { if (debug() >= 9) nodep->dumpTree("- newstmt: "); @@ -1409,12 +1405,10 @@ class TaskVisitor final : public VNVisitor { void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); VL_RESTORER(m_modNCalls); - { - m_modp = nodep; - m_insStmtp = nullptr; - m_modNCalls = 0; - iterateChildren(nodep); - } + m_modp = nodep; + m_insStmtp = nullptr; + m_modNCalls = 0; + iterateChildren(nodep); } void visit(AstWith* nodep) override { if (nodep->user1SetOnce()) { diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index 6022bc377..c136a90ce 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -883,10 +883,8 @@ class TraceVisitor final : public VNVisitor { } } VL_RESTORER(m_cfuncp); - { - m_cfuncp = nodep; - iterateChildren(nodep); - } + m_cfuncp = nodep; + iterateChildren(nodep); } void visit(AstTraceDecl* nodep) override { UINFO(8, " TRACE " << nodep << endl); diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index f89d1937a..0c518ebcd 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -460,46 +460,36 @@ class UndrivenVisitor final : public VNVisitorConst { // Don't know what black boxed calls do, assume in+out void visit(AstSysIgnore* nodep) override { VL_RESTORER(m_inBBox); - { - m_inBBox = true; - iterateChildrenConst(nodep); - } + m_inBBox = true; + iterateChildrenConst(nodep); } void visit(AstAssign* nodep) override { VL_RESTORER(m_inProcAssign); - { - m_inProcAssign = true; - iterateChildrenConst(nodep); - } + m_inProcAssign = true; + iterateChildrenConst(nodep); } void visit(AstAssignDly* nodep) override { VL_RESTORER(m_inProcAssign); - { - m_inProcAssign = true; - iterateChildrenConst(nodep); - } + m_inProcAssign = true; + iterateChildrenConst(nodep); } void visit(AstAssignW* nodep) override { VL_RESTORER(m_inContAssign); - { - m_inContAssign = true; - iterateChildrenConst(nodep); - } + m_inContAssign = true; + iterateChildrenConst(nodep); } void visit(AstAlways* nodep) override { VL_RESTORER(m_alwaysCombp); - { - AstNode::user2ClearTree(); - if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) { - UINFO(9, " " << nodep << endl); - m_alwaysCombp = nodep; - } else { - m_alwaysCombp = nullptr; - } - iterateChildrenConst(nodep); - if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9, " Done " << nodep << endl); + AstNode::user2ClearTree(); + if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) { + UINFO(9, " " << nodep << endl); + m_alwaysCombp = nodep; + } else { + m_alwaysCombp = nullptr; } + iterateChildrenConst(nodep); + if (nodep->keyword() == VAlwaysKwd::ALWAYS_COMB) UINFO(9, " Done " << nodep << endl); } void visit(AstNodeFTaskRef* nodep) override { VL_RESTORER(m_inFTaskRef); @@ -509,10 +499,8 @@ class UndrivenVisitor final : public VNVisitorConst { void visit(AstNodeFTask* nodep) override { VL_RESTORER(m_taskp); - { - m_taskp = nodep; - iterateChildrenConst(nodep); - } + m_taskp = nodep; + iterateChildrenConst(nodep); } void visit(AstPin* nodep) override { VL_RESTORER(m_inInoutPin); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 96d427b22..b68241674 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -179,43 +179,33 @@ class UnknownVisitor final : public VNVisitor { void visit(AstAssignDly* nodep) override { VL_RESTORER(m_assigndlyp); VL_RESTORER(m_timingControlp); - { - m_assigndlyp = nodep; - m_timingControlp = nodep->timingControlp(); - VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. - } + m_assigndlyp = nodep; + m_timingControlp = nodep->timingControlp(); + VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. } void visit(AstAssignW* nodep) override { VL_RESTORER(m_assignwp); VL_RESTORER(m_timingControlp); - { - m_assignwp = nodep; - m_timingControlp = nodep->timingControlp(); - VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. - } + m_assignwp = nodep; + m_timingControlp = nodep->timingControlp(); + VL_DO_DANGLING(iterateChildren(nodep), nodep); // May delete nodep. } void visit(AstNodeAssign* nodep) override { VL_RESTORER(m_timingControlp); - { - m_timingControlp = nodep->timingControlp(); - iterateChildren(nodep); - } + m_timingControlp = nodep->timingControlp(); + iterateChildren(nodep); } void visit(AstCaseItem* nodep) override { VL_RESTORER(m_constXCvt); - { - m_constXCvt = false; // Avoid losing the X's in casex - iterateAndNextNull(nodep->condsp()); - m_constXCvt = true; - iterateAndNextNull(nodep->stmtsp()); - } + m_constXCvt = false; // Avoid losing the X's in casex + iterateAndNextNull(nodep->condsp()); + m_constXCvt = true; + iterateAndNextNull(nodep->stmtsp()); } void visit(AstNodeDType* nodep) override { VL_RESTORER(m_constXCvt); - { - m_constXCvt = false; // Avoid losing the X's in casex - iterateChildren(nodep); - } + m_constXCvt = false; // Avoid losing the X's in casex + iterateChildren(nodep); } void visit(AstVar* nodep) override { VL_RESTORER(m_allowXUnique); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 87760c0bb..d302ac4c7 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -7963,36 +7963,28 @@ class WidthVisitor final : public VNVisitor { } void userIterate(AstNode* nodep, WidthVP* vup) { if (!nodep) return; - { - VL_RESTORER(m_vup); - m_vup = vup; - iterate(nodep); - } + VL_RESTORER(m_vup); + m_vup = vup; + iterate(nodep); } void userIterateAndNext(AstNode* nodep, WidthVP* vup) { if (!nodep) return; if (nodep->didWidth()) return; // Avoid iterating list we have already iterated - { - VL_RESTORER(m_vup); - m_vup = vup; - iterateAndNextNull(nodep); - } + VL_RESTORER(m_vup); + m_vup = vup; + iterateAndNextNull(nodep); } void userIterateChildren(AstNode* nodep, WidthVP* vup) { if (!nodep) return; - { - VL_RESTORER(m_vup); - m_vup = vup; - iterateChildren(nodep); - } + VL_RESTORER(m_vup); + m_vup = vup; + iterateChildren(nodep); } void userIterateChildrenBackwardsConst(AstNode* nodep, WidthVP* vup) { if (!nodep) return; - { - VL_RESTORER(m_vup); - m_vup = vup; - iterateChildrenBackwardsConst(nodep); - } + VL_RESTORER(m_vup); + m_vup = vup; + iterateChildrenBackwardsConst(nodep); } public: From 4257fcf9d0266a7063d4ce0f01b10c8b2d2e8942 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 12:08:37 -0500 Subject: [PATCH 047/171] Change parsing of cells to be non-symbol table sensitive. --- src/V3AstNodeDType.h | 5 +- src/V3AstNodeOther.h | 4 - src/V3AstNodes.cpp | 4 + src/V3LinkCells.cpp | 13 ++- src/V3LinkDot.cpp | 9 +++ src/V3ParseImp.cpp | 75 +++++++++++++++-- src/V3ParseImp.h | 5 +- src/verilog.y | 81 ++++++++++--------- test_regress/t/t_inst_paren_bad.out | 16 +++- .../t/t_interface_paren_missing_bad.out | 4 +- test_regress/t/t_json_only_tag.out | 2 +- test_regress/t/t_param_type_bad.out | 2 +- 12 files changed, 157 insertions(+), 63 deletions(-) diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 18d121cb7..2e0c658d5 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -855,11 +855,12 @@ class AstIfaceRefDType final : public AstNodeDType { // @astgen ptr := m_ifacep : Optional[AstIface] // Interface; cellp() should override // @astgen ptr := m_cellp : Optional[AstCell] // When exact parent cell known; not a guess // @astgen ptr := m_modportp : Optional[AstModport] // nullptr = unlinked or no modport - bool m_virtual = false; // True if virtual interface FileLine* m_modportFileline; // Where modport token was string m_cellName; // "" = no cell, such as when connects to 'input' iface string m_ifaceName; // Interface name string m_modportName; // "" = no modport + bool m_portDecl = false; // Interface_port_declaration + bool m_virtual = false; // True if virtual interface public: AstIfaceRefDType(FileLine* fl, const string& cellName, const string& ifaceName) : ASTGEN_SUPER_IfaceRefDType(fl) @@ -895,6 +896,8 @@ public: bool similarDType(const AstNodeDType* samep) const override { return this == samep; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } + bool isPortDecl() const { return m_portDecl; } + void isPortDecl(bool flag) { m_portDecl = flag; } bool isVirtual() const { return m_virtual; } void isVirtual(bool flag) { m_virtual = flag; diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 68fdbcd31..219397bac 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -807,7 +807,6 @@ class AstCell final : public AstNode { string m_origName; // Original name before dot addition string m_modName; // Module the cell instances bool m_hasIfaceVar : 1; // True if a Var has been created for this cell - bool m_hasNoParens : 1; // Instantiation has no parenthesis bool m_recursive : 1; // Self-recursive module bool m_trace : 1; // Trace this cell public: @@ -819,7 +818,6 @@ public: , m_origName{instName} , m_modName{modName} , m_hasIfaceVar{false} - , m_hasNoParens{false} , m_recursive{false} , m_trace{true} { this->addPinsp(pinsp); @@ -844,8 +842,6 @@ public: void modp(AstNodeModule* nodep) { m_modp = nodep; } bool hasIfaceVar() const { return m_hasIfaceVar; } void hasIfaceVar(bool flag) { m_hasIfaceVar = flag; } - bool hasNoParens() const { return m_hasNoParens; } - void hasNoParens(bool flag) { m_hasNoParens = flag; } void trace(bool flag) { m_trace = flag; } bool isTrace() const { return m_trace; } void recursive(bool flag) { m_recursive = flag; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 5a2ba837f..54987e853 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1779,6 +1779,8 @@ const char* AstEnumDType::broken() const { void AstEnumItemRef::dumpJson(std::ostream& str) const { dumpJsonGen(str); } void AstIfaceRefDType::dump(std::ostream& str) const { this->AstNodeDType::dump(str); + if (isPortDecl()) str << " [PORTDECL]"; + if (isVirtual()) str << " [VIRT]"; if (cellName() != "") str << " cell=" << cellName(); if (ifaceName() != "") str << " if=" << ifaceName(); if (modportName() != "") str << " mp=" << modportName(); @@ -1793,6 +1795,8 @@ void AstIfaceRefDType::dump(std::ostream& str) const { } } void AstIfaceRefDType::dumpJson(std::ostream& str) const { + dumpJsonBoolFunc(str, isPortDecl); + dumpJsonBoolFunc(str, isVirtual); dumpJsonStrFunc(str, cellName); dumpJsonStrFunc(str, ifaceName); dumpJsonStrFunc(str, modportName); diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 5263080b6..bd27b2f32 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -236,7 +236,11 @@ class LinkCellsVisitor final : public VNVisitor { if (!nodep->cellp()) nodep->ifacep(VN_AS(modp, Iface)); } else if (VN_IS(modp, NotFoundModule)) { // Will error out later } else { - nodep->v3error("Non-interface used as an interface: " << nodep->ifaceNameQ()); + nodep->v3error("Non-interface used as an interface: " + << nodep->ifaceNameQ() << "\n" + << nodep->warnMore() + + "... Perhaps intended an instantiation but " + "are missing parenthesis (IEEE 1800-2023 23.3.2)?"); } } iterateChildren(nodep); @@ -509,13 +513,6 @@ class LinkCellsVisitor final : public VNVisitor { nodep->hasIfaceVar(true); } } - if (nodep->hasNoParens()) { - // Need in the grammar, otherwise it looks like "id/*data_type*/ id/*new_var*/;" - nodep->v3error("Instantiation " << nodep->prettyNameQ() - << " requires parenthesis (IEEE 1800-2023 23.3.2)\n" - << nodep->warnMore() << "... Suggest use '" - << nodep->prettyName() << "()'"); - } if (nodep->modp()) { // iterateChildren(nodep); } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index af5c5c9b8..1e14a5d04 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -476,6 +476,15 @@ public: UINFO(9, " insAllIface se" << cvtToHex(varSymp) << " " << varp << endl); AstIfaceRefDType* const ifacerefp = ifaceRefFromArray(varp->subDTypep()); UASSERT_OBJ(ifacerefp, varp, "Non-ifacerefs on list!"); + const bool varGotPort = varp && varp->user4(); + if (ifacerefp->isPortDecl() && !varGotPort) { + varp->v3error("Interface port declaration " + << varp->prettyNameQ() << " doesn't have corresponding port\n" + << varp->warnMore() + + "... Perhaps intended an interface instantiation but " + "are missing parenthesis (IEEE 1800-2023 25.3)?"); + } + ifacerefp->isPortDecl(false); // Only needed for this warning; soon removing AstPort if (!ifacerefp->ifaceViaCellp()) { if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if // made mistake diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index df44d53a5..39d6ab56c 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -394,19 +394,75 @@ const V3ParseBisonYYSType* V3ParseImp::tokenPeekp(size_t depth) { return &m_tokensAhead.at(depth); } -size_t V3ParseImp::tokenPipeScanParam(size_t depth) { +size_t V3ParseImp::tokenPipeScanIdCell(size_t depthIn) { + // Search around IEEE module_instantiation/interface_instantiation/program_instantiation + // Return location of following token, or input if not found + // yaID/*module_identifier*/ [ '#' '('...')' ] yaID/*name_of_instance*/ [ '['...']' ] '(' ... + // yaID/*module_identifier*/ [ '#' id|etc ] yaID/*name_of_instance*/ [ '['...']' ] '(' ... + size_t depth = depthIn; + depth = tokenPipeScanParam(depth, true); + + if (tokenPeekp(depth)->token != yaID__LEX) return depthIn; + ++depth; + + depth = tokenPipeScanBracket(depth); // [ '['..']' ]* + if (tokenPeekp(depth)->token != '(') return depthIn; + + return depth; +} + +size_t V3ParseImp::tokenPipeScanBracket(size_t inDepth) { + // Return location of following token, or input if not found + // [ '['...']' ]* + int depth = inDepth; + int bra = 0; + while (tokenPeekp(depth)->token == '[') { + do { // Scan brackets + const int tok = tokenPeekp(depth)->token; + if (tok == 0) { // LCOV_EXCL_BR_LINE + UINFO(9, "tokenPipeScanBracket hit EOF; probably syntax error to come"); + return inDepth; // LCOV_EXCL_LINE + } else if (tok == '[') { + ++bra; + ++depth; + } else if (bra && tok == ']') { + --bra; + ++depth; + } else if (bra) { + ++depth; + } + } while (bra); + } + return depth; +} + +size_t V3ParseImp::tokenPipeScanParam(size_t inDepth, bool forCell) { // Search around IEEE parameter_value_assignment to see if :: follows // Return location of following token, or input if not found // yaID [ '#(' ... ')' ] - if (tokenPeekp(depth)->token != '#') return depth; - if (tokenPeekp(depth + 1)->token != '(') return depth; - depth += 2; // Past the ( + // if forCell: yaID [ '#' number/etc ] + int depth = inDepth; + if (tokenPeekp(depth)->token != '#') return inDepth; + ++depth; + + if (tokenPeekp(depth)->token != '(') { + if (!forCell) return inDepth; + // For module cells, we can have '#' and a number, or, annoyingly an idDotted + int ntoken = tokenPeekp(depth)->token; + if (ntoken == yaINTNUM || ntoken == yaFLOATNUM || ntoken == yaTIMENUM + || ntoken == yaID__LEX) { + ++depth; + return depth; + } + return inDepth; // Miss + } + ++depth; int parens = 1; // Count first ( while (true) { const int tok = tokenPeekp(depth)->token; if (tok == 0) { // LCOV_EXCL_BR_LINE UINFO(9, "tokenPipeScanParam hit EOF; probably syntax error to come"); - break; // LCOV_EXCL_LINE + return inDepth; // LCOV_EXCL_LINE } else if (tok == '(') { ++parens; } else if (tok == ')') { @@ -450,12 +506,17 @@ size_t V3ParseImp::tokenPipeScanTypeEq(size_t depth) { int V3ParseImp::tokenPipelineId(int token) { const V3ParseBisonYYSType* nexttokp = tokenPeekp(0); // First char after yaID const int nexttok = nexttokp->token; + UINFO(9, "tokenPipelineId tok=" << yylval.token << endl); UASSERT(yylval.token == yaID__LEX, "Start with ID"); if (nexttok == yP_COLONCOLON) { return yaID__CC; } VL_RESTORER(yylval); // Remember value, as about to read ahead + if (m_tokenLastBison.token != '@' && m_tokenLastBison.token != '#' + && m_tokenLastBison.token != '.') { + if (const size_t depth = tokenPipeScanIdCell(0)) return yaID__aCELL; + } if (nexttok == '#') { VL_RESTORER(yylval); // Remember value, as about to read ahead - const size_t depth = tokenPipeScanParam(0); + const size_t depth = tokenPipeScanParam(0, false); if (tokenPeekp(depth)->token == yP_COLONCOLON) return yaID__CC; } return token; @@ -662,6 +723,7 @@ int V3ParseImp::tokenToBison() { // Called as global since bison doesn't have our pointer tokenPipelineSym(); // sets yylval m_bisonLastFileline = yylval.fl; + m_tokenLastBison = yylval; // yylval.scp = nullptr; // Symbol table not yet needed - no packages if (debug() >= 6 || debugFlex() >= 6 @@ -680,6 +742,7 @@ std::ostream& operator<<(std::ostream& os, const V3ParseBisonYYSType& rhs) { if (rhs.token == yaID__ETC // || rhs.token == yaID__CC // || rhs.token == yaID__LEX // + || rhs.token == yaID__aCELL // || rhs.token == yaID__aTYPE) { os << " strp='" << *(rhs.strp) << "'"; } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index d54b714c9..82e8e4fcb 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -156,6 +156,7 @@ class V3ParseImp final { int m_lexPrevToken = 0; // previous parsed token (for lexer) bool m_afterColonColon = false; // The previous token was '::' + V3ParseBisonYYSType m_tokenLastBison; // Token we last sent to Bison std::deque m_tokensAhead; // Tokens we parsed ahead of parser std::deque m_stringps; // Created strings for later cleanup @@ -312,7 +313,9 @@ private: void tokenPipeline() VL_MT_DISABLED; // Internal; called from tokenToBison int tokenPipelineId(int token) VL_MT_DISABLED; void tokenPipelineSym() VL_MT_DISABLED; - size_t tokenPipeScanParam(size_t depth) VL_MT_DISABLED; + size_t tokenPipeScanIdCell(size_t depth) VL_MT_DISABLED; + size_t tokenPipeScanBracket(size_t depth) VL_MT_DISABLED; + size_t tokenPipeScanParam(size_t depth, bool forCell) VL_MT_DISABLED; size_t tokenPipeScanTypeEq(size_t depth) VL_MT_DISABLED; const V3ParseBisonYYSType* tokenPeekp(size_t depth) VL_MT_DISABLED; void preprocDumps(std::ostream& os, bool forInputs) VL_MT_DISABLED; diff --git a/src/verilog.y b/src/verilog.y index 17e484999..6129562ef 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -135,21 +135,9 @@ public: string newtext = GRAMMARP->unquoteString(fileline, text); return new AstText{fileline, newtext}; } - AstNode* createCellOrIfaceRef(FileLine* fileline, const string& name, AstPin* pinlistp, - AstNodeRange* rangelistp, bool parens) { + AstNode* createCell(FileLine* fileline, const string& name, AstPin* pinlistp, + AstNodeRange* rangelistp) { // Must clone m_instParamp as may be comma'ed list of instances - VSymEnt* const foundp = SYMP->symCurrentp()->findIdFallback(name); - if (foundp && VN_IS(foundp->nodep(), Port)) { - // It's a non-ANSI interface, not a cell declaration - m_varAttrp = nullptr; - m_varDecl = VVarType::IFACEREF; - m_varIO = VDirection::NONE; - m_varLifetime = VLifetime::NONE; - setDType(new AstIfaceRefDType{fileline, "", GRAMMARP->m_instModule}); - m_varDeclTyped = true; - AstVar* const nodep = createVariable(fileline, name, rangelistp, nullptr); - return nodep; - } AstCell* const nodep = new AstCell{ fileline, GRAMMARP->m_instModuleFl, @@ -158,7 +146,6 @@ public: pinlistp, (GRAMMARP->m_instParamp ? GRAMMARP->m_instParamp->cloneTree(true) : nullptr), GRAMMARP->scrubRange(rangelistp)}; - nodep->hasNoParens(!parens); nodep->trace(GRAMMARP->allTracingOn(fileline)); return nodep; } @@ -450,6 +437,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yaID__ETC "IDENTIFIER" %token yaID__CC "IDENTIFIER-::" %token yaID__LEX "IDENTIFIER-in-lex" +%token yaID__aCELL "IDENTIFIER-for-cell" %token yaID__aTYPE "IDENTIFIER-for-type" // Can't predecode aFUNCTION, can declare after use // Can't predecode aINTERFACE, can declare after use @@ -1433,6 +1421,7 @@ parameter_value_assignmentClassE: // IEEE: [ parameter_value_assignme parameter_value_assignmentInst: // IEEE: parameter_value_assignment for instance '#' '(' cellparamListE ')' { $$ = $3; } // // Parentheses are optional around a single parameter + // // IMPORTANT: Below hardcoded in tokenPipeScanParam | '#' yaINTNUM { $$ = new AstPin{$2, 1, "", new AstConst{$2, *$2}}; } | '#' yaFLOATNUM { $$ = new AstPin{$2, 1, "", new AstConst{$2, AstConst::RealDouble{}, $2}}; } @@ -2071,9 +2060,26 @@ port_declaration: // ==IEEE: port_declaration | port_directionReset port_declNetE /*implicit*/ /*mid*/ { VARDTYPE_NDECL(nullptr); /*default_nettype*/ } /*cont*/ list_of_variable_decl_assignments { $$ = $4; } - // // IEEE: interface_declaration - // // Looks just like variable declaration unless has a period - // // See etcInst + // + // // IEEE: interface_port_declaration + // // IEEE: interface_identifier list_of_interface_identifiers + | id/*interface*/ + /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); + AstIfaceRefDType* const dtp = new AstIfaceRefDType{$1, "", *$1}; + dtp->isPortDecl(true); + VARDTYPE(dtp); } + /*cont*/ mpInstnameList + { $$ = VARDONEP($3, nullptr, nullptr); } + // // IEEE: interface_port_declaration + // // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers + | id/*interface*/ '.' idAny/*modport*/ + /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); + AstIfaceRefDType* const dtp = new AstIfaceRefDType{$1, $3, "", *$1, *$3}; + dtp->isPortDecl(true); + VARDTYPE(dtp); } + /*cont*/ mpInstnameList + { $$ = VARDONEP($5, nullptr, nullptr); } + //UNSUP: strengthSpecE for udp_instantiations ; tf_port_declaration: // ==IEEE: tf_port_declaration @@ -3259,10 +3265,9 @@ etcInst: // IEEE: module_instantiation + gate_instantiati ; instDecl: - // // Currently disambiguated from data_declaration based on - // // VARs being type, and cells non-type. - // // IEEE requires a '(' to disambiguate, we need TODO force this - id parameter_value_assignmentInstE + // // Disambigurated from data_declaration based on + // // idCell which is found as IEEE requires a later '(' + idCell parameter_value_assignmentInstE /*mid*/ { INSTPREP($1, *$1, $2); } /*cont*/ instnameList ';' { $$ = $4; @@ -3271,14 +3276,7 @@ instDecl: VL_DO_CLEAR(GRAMMARP->m_instParamp->deleteTree(), GRAMMARP->m_instParamp = nullptr); } } - // // IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers - | id/*interface*/ '.' idAny/*modport*/ - /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); - AstNodeDType* const dtp = new AstIfaceRefDType{$1, $3, "", *$1, *$3}; - VARDTYPE(dtp); } - /*cont*/ mpInstnameList ';' - { $$ = VARDONEP($5, nullptr, nullptr); } - //UNSUP: strengthSpecE for udp_instantiations + // // // IEEE: part of udp_instance when no name_of_instance // // Note no unpacked dimension nor list of instances | id @@ -3303,14 +3301,12 @@ instnameList: instnameParen: id instRangeListE '(' cellpinListE ')' - { $$ = GRAMMARP->createCellOrIfaceRef($1, *$1, $4, $2, true); } - | id instRangeListE - { $$ = GRAMMARP->createCellOrIfaceRef($1, *$1, nullptr, $2, false); } + { $$ = GRAMMARP->createCell($1, *$1, $4, $2); } ; instnameParenUdpn: // IEEE: part of udp_instance when no name_of_instance '(' cellpinListE ')' // When UDP has empty name, unpacked dimensions must not be used - { $$ = GRAMMARP->createCellOrIfaceRef($1, "", $2, nullptr, true); } + { $$ = GRAMMARP->createCell($1, "", $2, nullptr); } ; instRangeListE: @@ -4661,12 +4657,12 @@ funcId: // IEEE: function_data_type_or_implicit + part o { $$ = $2; $$->fvarp($1); SYMP->pushNewUnderNodeOrCurrent($$, $2); } - | packageClassScopeE idType packed_dimensionListE fIdScoped + | packageClassScopeE idCellType packed_dimensionListE fIdScoped { AstRefDType* const refp = new AstRefDType{$2, *$2, $1, nullptr}; $$ = $4; $$->fvarp(GRAMMARP->createArray(refp, $3, true)); SYMP->pushNewUnderNodeOrCurrent($$, $4); } - | packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE fIdScoped + | packageClassScopeE idCellType parameter_value_assignmentClass packed_dimensionListE fIdScoped { AstRefDType* const refp = new AstRefDType{$2, *$2, $1, $3}; $$ = $5; $$->fvarp(GRAMMARP->createArray(refp, $4, true)); @@ -5784,15 +5780,28 @@ id: idAny: // Any kind of identifier yaID__ETC { $$ = $1; $$ = $1; } + | yaID__aCELL { $$ = $1; $$ = $1; } | yaID__aTYPE { $$ = $1; $$ = $1; } | idRandomize { $$ = $1; $$ = $1; } ; +idCell: // IEEE: instance_identifier or similar with another id then '(' + // // See V3ParseImp::tokenPipeScanIdCell + // // [^': '@' '.'] yaID/*module_id*/ [ '#' '('...')' ] yaID/*name_of_instance*/ [ '['...']' ] '(' ... + // // [^':' @' '.'] yaID/*module_id*/ [ '#' id|etc ] yaID/*name_of_instance*/ [ '['...']' ] '(' ... + yaID__aCELL { $$ = $1; $$ = $1; } + ; + idType: // IEEE: class_identifier or other type identifier // // Used where reference is needed yaID__aTYPE { $$ = $1; $$ = $1; } ; +idCellType: // type_identifier for functions which have a following id then '(' + yaID__aCELL { $$ = $1; $$ = $1; } + | yaID__aTYPE { $$ = $1; $$ = $1; } + ; + idCC: // IEEE: class/package then :: // lexer matches this: yaID_LEX [ '#' '(' ... ')' ] yP_COLONCOLON yaID__CC { $$ = $1; $$ = $1; } diff --git a/test_regress/t/t_inst_paren_bad.out b/test_regress/t/t_inst_paren_bad.out index e19bc13b5..b802de3e6 100644 --- a/test_regress/t/t_inst_paren_bad.out +++ b/test_regress/t/t_inst_paren_bad.out @@ -1,5 +1,15 @@ -%Error: t/t_inst_paren_bad.v:11:8: Instantiation 'sub_inst' requires parenthesis (IEEE 1800-2023 23.3.2) - : ... Suggest use 'sub_inst()' +%Error: t/t_inst_paren_bad.v:11:4: Non-interface used as an interface: 'sub' + : ... Perhaps intended an instantiation but are missing parenthesis (IEEE 1800-2023 23.3.2)? 11 | sub sub_inst; - | ^~~~~~~~ + | ^~~ +%Warning-MULTITOP: t/t_inst_paren_bad.v:10:8: Multiple top level modules + : ... Suggest see manual; fix the duplicates, or use --top-module to select top. + ... For warning description see https://verilator.org/warn/MULTITOP?v=latest + ... Use "/* verilator lint_off MULTITOP */" and lint_on around source to disable this message. + : ... Top module 'sub' + 7 | module sub; + | ^~~ + : ... Top module 't' + 10 | module t( ); + | ^ %Error: Exiting due to diff --git a/test_regress/t/t_interface_paren_missing_bad.out b/test_regress/t/t_interface_paren_missing_bad.out index 70a167b83..a0b038347 100644 --- a/test_regress/t/t_interface_paren_missing_bad.out +++ b/test_regress/t/t_interface_paren_missing_bad.out @@ -1,5 +1,5 @@ -%Error: t/t_interface_paren_missing_bad.v:13:9: Instantiation 'intf_i' requires parenthesis (IEEE 1800-2023 23.3.2) - : ... Suggest use 'intf_i()' +%Error: t/t_interface_paren_missing_bad.v:13:9: Interface port declaration 'intf_i' doesn't have corresponding port + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? 13 | intf intf_i; | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_json_only_tag.out b/test_regress/t/t_json_only_tag.out index 393a928fa..af48c3d40 100644 --- a/test_regress/t/t_json_only_tag.out +++ b/test_regress/t/t_json_only_tag.out @@ -74,7 +74,7 @@ {"type":"MEMBERDTYPE","name":"enable","addr":"(UB)","loc":"d,23:19,23:25","dtypep":"(UB)","generic":false,"childDTypep": [],"valuep": []}, {"type":"MEMBERDTYPE","name":"data","addr":"(VB)","loc":"d,24:19,24:23","dtypep":"(VB)","generic":false,"childDTypep": [],"valuep": []} ]}, - {"type":"IFACEREFDTYPE","name":"","addr":"(O)","loc":"d,29:8,29:12","dtypep":"(O)","cellName":"itop","ifaceName":"ifc","modportName":"","generic":false,"ifacep":"UNLINKED","cellp":"(L)","modportp":"UNLINKED","paramsp": []}, + {"type":"IFACEREFDTYPE","name":"","addr":"(O)","loc":"d,29:8,29:12","dtypep":"(O)","isPortDecl":false,"isVirtual":false,"cellName":"itop","ifaceName":"ifc","modportName":"","generic":false,"ifacep":"UNLINKED","cellp":"(L)","modportp":"UNLINKED","paramsp": []}, {"type":"BASICDTYPE","name":"logic","addr":"(S)","loc":"d,31:27,31:28","dtypep":"(S)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, {"type":"REFDTYPE","name":"my_struct","addr":"(WB)","loc":"d,31:4,31:13","dtypep":"(K)","generic":false,"typedefp":"UNLINKED","refDTypep":"(K)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []}, {"type":"UNPACKARRAYDTYPE","name":"","addr":"(Q)","loc":"d,31:26,31:27","dtypep":"(Q)","isCompound":false,"declRange":"[0:1]","generic":false,"refDTypep":"(WB)","childDTypep": [], diff --git a/test_regress/t/t_param_type_bad.out b/test_regress/t/t_param_type_bad.out index 2c7ea7959..316eab2ba 100644 --- a/test_regress/t/t_param_type_bad.out +++ b/test_regress/t/t_param_type_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER, expecting IDENTIFIER or IDENTIFIER-for-type or randomize +%Error: t/t_param_type_bad.v:9:27: syntax error, unexpected INTEGER NUMBER, expecting IDENTIFIER or IDENTIFIER-for-cell or IDENTIFIER-for-type or randomize 9 | localparam type bad2 = 2; | ^ %Error: Exiting due to From 03bd1bfc639cc1e61a4b78ec40d4fadb6dc8715d Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 10 Nov 2024 17:23:11 +0000 Subject: [PATCH 048/171] Move Concat balancing from DFG to FuncOpt (#5602) This means it applies more widely, e.g. inside sequential logic. --- docs/guide/exe_verilator.rst | 2 + src/CMakeLists.txt | 1 - src/Makefile_obj.in | 1 - src/V3Dfg.h | 3 - src/V3DfgBalanceTrees.cpp | 197 ------------------ src/V3DfgOptimizer.cpp | 4 +- src/V3DfgOptimizer.h | 2 +- src/V3DfgPasses.cpp | 11 +- src/V3DfgPasses.h | 16 +- src/V3FuncOpt.cpp | 157 +++++++++++++- src/V3Options.cpp | 2 + src/V3Options.h | 4 +- src/Verilator.cpp | 4 +- ..._dfg_balance_cats.py => t_balance_cats.py} | 7 +- ...{t_dfg_balance_cats.v => t_balance_cats.v} | 0 ...ats_nofunc.py => t_balance_cats_nofunc.py} | 9 +- test_regress/t/t_opt_const_dfg.py | 2 +- 17 files changed, 174 insertions(+), 248 deletions(-) delete mode 100644 src/V3DfgBalanceTrees.cpp rename test_regress/t/{t_dfg_balance_cats.py => t_balance_cats.py} (55%) rename test_regress/t/{t_dfg_balance_cats.v => t_balance_cats.v} (100%) rename test_regress/t/{t_dfg_balance_cats_nofunc.py => t_balance_cats_nofunc.py} (53%) diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index e70f70b71..1ec0efd4e 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -591,6 +591,8 @@ Summary: .. option:: -fno-func-opt +.. option:: -fno-func-opt-balance-cat + .. option:: -fno-func-opt-split-cat .. option:: -fno-gate diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9b1aac1d0..d9b43d17a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -225,7 +225,6 @@ set(COMMON_SOURCES V3Descope.cpp V3Dfg.cpp V3DfgAstToDfg.cpp - V3DfgBalanceTrees.cpp V3DfgCache.cpp V3DfgDecomposition.cpp V3DfgDfgToAst.cpp diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 0945e4690..adfcb2215 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -238,7 +238,6 @@ RAW_OBJS_PCH_ASTNOMT = \ V3Descope.o \ V3Dfg.o \ V3DfgAstToDfg.o \ - V3DfgBalanceTrees.o \ V3DfgCache.o \ V3DfgDecomposition.o \ V3DfgDfgToAst.o \ diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 8b0978b97..5fab278ee 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -274,9 +274,6 @@ public: // Predicate: has 1 or more sinks bool hasSinks() const { return m_sinksp != nullptr; } - // Predicate: has precisely 1 sink - bool hasSingleSink() const { return m_sinksp && !m_sinksp->m_nextp; } - // Predicate: has 2 or more sinks bool hasMultipleSinks() const { return m_sinksp && m_sinksp->m_nextp; } diff --git a/src/V3DfgBalanceTrees.cpp b/src/V3DfgBalanceTrees.cpp deleted file mode 100644 index 6b5eca2d8..000000000 --- a/src/V3DfgBalanceTrees.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// -*- mode: C++; c-file-style: "cc-mode" -*- -//************************************************************************* -// DESCRIPTION: Verilator: Balance associative op trees in DfgGraphs -// -// Code available from: https://verilator.org -// -//************************************************************************* -// -// Copyright 2003-2024 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 -// -//************************************************************************* -// -// - Convert concatenation trees into balanced form -// -//************************************************************************* - -#include "V3PchAstNoMT.h" // VL_MT_DISABLED_CODE_UNIT - -#include "V3Dfg.h" -#include "V3DfgPasses.h" - -VL_DEFINE_DEBUG_FUNCTIONS; - -class DfgBalanceTrees final { - // We keep the expressions, together with their offsets within a concatenation tree - struct ConcatTerm final { - DfgVertex* vtxp = nullptr; - size_t offset = 0; - - ConcatTerm() = default; - ConcatTerm(DfgVertex* vtxp, size_t offset) - : vtxp{vtxp} - , offset{offset} {} - }; - - DfgGraph& m_dfg; // The graph being processed - V3DfgBalanceTreesContext& m_ctx; // The optimization context for stats - - // Is the given vertex the root of a tree (of potentially size 1), of the given type? - template - static bool isRoot(const DfgVertex& vtx) { - static_assert(std::is_base_of::value, - "'Vertex' must be a 'DfgVertexBinary'"); - if (!vtx.is()) return false; - // Has a single sink, and that sink is not another vertex of the same type - return vtx.hasSingleSink() && !vtx.findSink(); - } - - // Recursive implementation of 'gatherTerms' below. - template - static void gatherTermsImpl(DfgVertex* vtxp, std::vector& terms) { - // Base case: different type, or multiple sinks -> it's a term - if (!vtxp->is() || vtxp->hasMultipleSinks()) { - terms.emplace_back(vtxp); - return; - } - // Recursive case: gather sub terms, right to right - DfgVertexBinary* const binp = vtxp->as(); - gatherTermsImpl(binp->rhsp(), terms); - gatherTermsImpl(binp->lhsp(), terms); - } - - // Gather terms in the tree of given type, rooted at the given vertex. - // Results are right to left, that is, index 0 in the returned vector - // is the rightmost term, index size()-1 is the leftmost term. - template - static std::vector gatherTerms(Vertex& root) { - static_assert(std::is_base_of::value, - "'Vertex' must be a 'DfgVertexBinary'"); - std::vector terms; - gatherTermsImpl(root.rhsp(), terms); - gatherTermsImpl(root.lhsp(), terms); - return terms; - } - - // Construct a balanced concatenation from the given terms, - // between indices begin (inclusive), and end (exclusive). - // Note term[end].offset must be valid. term[end].vtxp is - // never referenced. - DfgVertex* constructConcat(const std::vector& terms, const size_t begin, - const size_t end) { - UASSERT(end < terms.size(), "Invalid end"); - UASSERT(begin < end, "Invalid range"); - // Base case: just return the term - if (end == begin + 1) return terms[begin].vtxp; - - // Recursive case: - // Compute the mid-point, trying to create roughly equal width intermediates - const size_t width = terms[end].offset - terms[begin].offset; - const size_t midOffset = width / 2 + terms[begin].offset; - const auto beginIt = terms.begin() + begin; - const auto endIt = terms.begin() + end; - const auto midIt = std::lower_bound(beginIt + 1, endIt - 1, midOffset, // - [&](const ConcatTerm& term, size_t value) { // - return term.offset < value; - }); - const size_t mid = begin + std::distance(beginIt, midIt); - UASSERT(begin < mid && mid < end, "Must make some progress"); - // Construct the subtrees - DfgVertex* const rhsp = constructConcat(terms, begin, mid); - DfgVertex* const lhsp = constructConcat(terms, mid, end); - // Construct new node - AstNodeDType* const dtypep = DfgVertex::dtypeForWidth(lhsp->width() + rhsp->width()); - DfgConcat* const newp = new DfgConcat{m_dfg, lhsp->fileline(), dtypep}; - newp->rhsp(rhsp); - newp->lhsp(lhsp); - return newp; - } - - // Delete unused tree rooted at the given vertex - void deleteTree(DfgVertexBinary* const vtxp) { - UASSERT_OBJ(!vtxp->hasSinks(), vtxp, "Trying to remove used vertex"); - DfgVertexBinary* const lhsp = vtxp->lhsp()->cast(); - DfgVertexBinary* const rhsp = vtxp->rhsp()->cast(); - VL_DO_DANGLING(vtxp->unlinkDelete(m_dfg), vtxp); - if (lhsp && !lhsp->hasSinks()) deleteTree(lhsp); - if (rhsp && !rhsp->hasSinks()) deleteTree(rhsp); - } - - void balanceConcat(DfgConcat* const rootp) { - // Gather all input vertices of the tree - const std::vector vtxps = gatherTerms(*rootp); - // Don't bother with trivial trees - if (vtxps.size() <= 3) return; - - // Construct the terms Vector that we are going to do processing on - std::vector terms(vtxps.size() + 1); - // These are redundant (constructor does the same), but here they are for clarity - terms[0].offset = 0; - terms[vtxps.size()].vtxp = nullptr; - for (size_t i = 0; i < vtxps.size(); ++i) { - terms[i].vtxp = vtxps[i]; - terms[i + 1].offset = terms[i].offset + vtxps[i]->width(); - } - - // Round 1: try to create terms ending on VL_EDATASIZE boundaries. - // This ensures we pack bits within a VL_EDATASIZE first is possible, - // and then hopefully we can just assemble VL_EDATASIZE words afterward. - std::vector terms2; - { - terms2.reserve(terms.size()); - - size_t begin = 0; // Start of current range considered - size_t end = 0; // End of current range considered - size_t offset = 0; // Offset of current range considered - - // Create a term from the current range - const auto makeTerm = [&]() { - DfgVertex* const vtxp = constructConcat(terms, begin, end); - terms2.emplace_back(vtxp, offset); - offset += vtxp->width(); - begin = end; - }; - - // Create all terms ending on a boundary. - while (++end < terms.size() - 1) { - if (terms[end].offset % VL_EDATASIZE == 0) makeTerm(); - } - // Final term. Loop condition above ensures this always exists, - // and might or might not be on a boundary. - makeTerm(); - // Sentinel term - terms2.emplace_back(nullptr, offset); - // should have ended up with the same number of bits at least... - UASSERT(terms2.back().offset == terms.back().offset, "Inconsitent terms"); - } - - // Round 2: Combine the partial terms - rootp->replaceWith(constructConcat(terms2, 0, terms2.size() - 1)); - VL_DO_DANGLING(deleteTree(rootp), rootp); - - ++m_ctx.m_balancedConcats; - } - - DfgBalanceTrees(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) - : m_dfg{dfg} - , m_ctx{ctx} { - // Find all roots - std::vector rootps; - for (DfgVertex& vtx : dfg.opVertices()) { - if (isRoot(vtx)) rootps.emplace_back(vtx.as()); - } - // Balance them - for (DfgConcat* const rootp : rootps) balanceConcat(rootp); - } - -public: - static void apply(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) { DfgBalanceTrees{dfg, ctx}; } -}; - -void V3DfgPasses::balanceTrees(DfgGraph& dfg, V3DfgBalanceTreesContext& ctx) { - DfgBalanceTrees::apply(dfg, ctx); -} diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index 7297cdd85..d6c6f1f30 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -236,7 +236,7 @@ void V3DfgOptimizer::extract(AstNetlist* netlistp) { V3Global::dumpCheckGlobalTree("dfg-extract", 0, dumpTreeEitherLevel() >= 3); } -void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label, bool lastInvocation) { +void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label) { UINFO(2, __FUNCTION__ << ": " << endl); // NODE STATE @@ -282,7 +282,7 @@ void V3DfgOptimizer::optimize(AstNetlist* netlistp, const string& label, bool la for (auto& component : acyclicComponents) { if (dumpDfgLevel() >= 7) component->dumpDotFilePrefixed(ctx.prefix() + "source"); // Optimize the component - V3DfgPasses::optimize(*component, ctx, lastInvocation); + V3DfgPasses::optimize(*component, ctx); // Add back under the main DFG (we will convert everything back in one go) dfg->addGraph(*component); } diff --git a/src/V3DfgOptimizer.h b/src/V3DfgOptimizer.h index df67c3e53..067b5e801 100644 --- a/src/V3DfgOptimizer.h +++ b/src/V3DfgOptimizer.h @@ -29,7 +29,7 @@ namespace V3DfgOptimizer { void extract(AstNetlist*) VL_MT_DISABLED; // Optimize the design -void optimize(AstNetlist*, const string& label, bool lastInvocation) VL_MT_DISABLED; +void optimize(AstNetlist*, const string& label) VL_MT_DISABLED; } // namespace V3DfgOptimizer #endif // Guard diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index 5b3f04041..d67642e8c 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -42,11 +42,6 @@ V3DfgEliminateVarsContext::~V3DfgEliminateVarsContext() { m_varsRemoved); } -V3DfgBalanceTreesContext::~V3DfgBalanceTreesContext() { - V3Stats::addStat("Optimizations, DFG " + m_label + " BalanceTrees, concat trees balanced", - m_balancedConcats); -} - static std::string getPrefix(const std::string& label) { if (label.empty()) return ""; std::string str = VString::removeWhitespace(label); @@ -337,7 +332,7 @@ void V3DfgPasses::eliminateVars(DfgGraph& dfg, V3DfgEliminateVarsContext& ctx) { for (AstVar* const varp : replacedVariables) varp->unlinkFrBack()->deleteTree(); } -void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx, bool lastInvocation) { +void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx) { // There is absolutely nothing useful we can do with a graph of size 2 or less if (dfg.size() <= 2) return; @@ -365,10 +360,6 @@ void V3DfgPasses::optimize(DfgGraph& dfg, V3DfgOptimizationContext& ctx, bool la } // Accumulate patterns for reporting if (v3Global.opt.stats()) ctx.m_patternStats.accumulate(dfg); - // The peephole pass covnerts all trees to right leaning, so only do this on the last DFG run. - if (lastInvocation) { - apply(4, "balanceTrees", [&]() { balanceTrees(dfg, ctx.m_balanceTreesContext); }); - } apply(4, "regularize", [&]() { regularize(dfg, ctx.m_regularizeContext); }); if (dumpDfgLevel() >= 8) dfg.dumpDotAllVarConesPrefixed(ctx.prefix() + "optimized"); } diff --git a/src/V3DfgPasses.h b/src/V3DfgPasses.h index d893c84ce..2b1e08aa6 100644 --- a/src/V3DfgPasses.h +++ b/src/V3DfgPasses.h @@ -68,17 +68,6 @@ public: ~V3DfgEliminateVarsContext() VL_MT_DISABLED; }; -class V3DfgBalanceTreesContext final { - const std::string m_label; // Label to apply to stats - -public: - VDouble0 m_balancedConcats; // Number of temporaries introduced - - explicit V3DfgBalanceTreesContext(const std::string& label) - : m_label{label} {} - ~V3DfgBalanceTreesContext() VL_MT_DISABLED; -}; - class V3DfgOptimizationContext final { const std::string m_label; // Label to add to stats, etc. const std::string m_prefix; // Prefix to add to file dumps (derived from label) @@ -103,7 +92,6 @@ public: V3DfgPeepholeContext m_peepholeContext{m_label}; V3DfgRegularizeContext m_regularizeContext{m_label}; V3DfgEliminateVarsContext m_eliminateVarsContext{m_label}; - V3DfgBalanceTreesContext m_balanceTreesContext{m_label}; V3DfgPatternStats m_patternStats; @@ -124,7 +112,7 @@ namespace V3DfgPasses { DfgGraph* astToDfg(AstModule&, V3DfgOptimizationContext&) VL_MT_DISABLED; // Optimize the given DfgGraph -void optimize(DfgGraph&, V3DfgOptimizationContext&, bool lastInvocation) VL_MT_DISABLED; +void optimize(DfgGraph&, V3DfgOptimizationContext&) VL_MT_DISABLED; // Convert DfgGraph back into Ast, and insert converted graph back into its parent module. // Returns the parent module. @@ -146,8 +134,6 @@ void regularize(DfgGraph&, V3DfgRegularizeContext&) VL_MT_DISABLED; void removeUnused(DfgGraph&) VL_MT_DISABLED; // Eliminate (remove or replace) redundant variables. Also removes resulting unused logic. void eliminateVars(DfgGraph&, V3DfgEliminateVarsContext&) VL_MT_DISABLED; -// Make computation trees balanced -void balanceTrees(DfgGraph&, V3DfgBalanceTreesContext&) VL_MT_DISABLED; } // namespace V3DfgPasses diff --git a/src/V3FuncOpt.cpp b/src/V3FuncOpt.cpp index f71621a24..5cfea84bd 100644 --- a/src/V3FuncOpt.cpp +++ b/src/V3FuncOpt.cpp @@ -21,6 +21,12 @@ // foo[_:_] = r; // foo[_:_] = l; // +// - Balance concatenation trees, e.g.: +// {a, {b, {c, d}} +// becomes: +// {{a, b}, {c, d}} +// Reality is more complex here, see the code. +// //************************************************************************* #include "V3PchAstMT.h" @@ -33,11 +39,144 @@ VL_DEFINE_DEBUG_FUNCTIONS; +class BalanceConcatTree final { + // STATELESS + + // We keep the expressions, together with their offsets within a concatenation tree + struct Term final { + AstNodeExpr* exprp = nullptr; + size_t offset = 0; + + Term() = default; + Term(AstNodeExpr* exprp, size_t offset) + : exprp{exprp} + , offset{offset} {} + }; + + // Recursive implementation of 'gatherTerms' below. + static void gatherTermsRecursive(AstNodeExpr* exprp, std::vector& terms) { + if (AstConcat* const catp = VN_CAST(exprp, Concat)) { + // Recursive case: gather sub terms, right to left + gatherTermsRecursive(catp->rhsp(), terms); + gatherTermsRecursive(catp->lhsp(), terms); + return; + } + + // Base case: different operation + terms.emplace_back(exprp); + } + + // Gather terms in the tree rooted at the given node. + // Results are right to left, that is, index 0 in the returned vector + // is the rightmost term, index size()-1 is the leftmost term. + static std::vector gatherTerms(AstConcat* rootp) { + std::vector terms; + gatherTermsRecursive(rootp->rhsp(), terms); + gatherTermsRecursive(rootp->lhsp(), terms); + return terms; + } + + // Construct a balanced concatenation from the given terms, + // between indices begin (inclusive), and end (exclusive). + // Note term[end].offset must be valid. term[end].vtxp is + // never referenced. + static AstNodeExpr* construct(const std::vector& terms, const size_t begin, + const size_t end) { + UASSERT(end < terms.size(), "Invalid end"); + UASSERT(begin < end, "Invalid range"); + // Base case: just return the term + if (end == begin + 1) return terms[begin].exprp; + + // Recursive case: + // Compute the mid-point, trying to create roughly equal width intermediates + const size_t width = terms[end].offset - terms[begin].offset; + const size_t midOffset = width / 2 + terms[begin].offset; + const auto beginIt = terms.begin() + begin; + const auto endIt = terms.begin() + end; + const auto midIt = std::lower_bound(beginIt + 1, endIt - 1, midOffset, // + [&](const Term& term, size_t value) { // + return term.offset < value; + }); + const size_t mid = begin + std::distance(beginIt, midIt); + UASSERT(begin < mid && mid < end, "Must make some progress"); + // Construct the subtrees + AstNodeExpr* const rhsp = construct(terms, begin, mid); + AstNodeExpr* const lhsp = construct(terms, mid, end); + // Construct new node + AstNodeExpr* newp = new AstConcat{lhsp->fileline(), lhsp, rhsp}; + newp->user1(true); // Must not attempt to balance again. + return newp; + } + + // Returns replacement node, or nullptr if no change + static AstConcat* balance(AstConcat* const rootp) { + UINFO(9, "balanceConcat " << rootp << "\n"); + // Gather all input vertices of the tree + const std::vector exprps = gatherTerms(rootp); + // Don't bother with trivial trees + if (exprps.size() <= 3) return nullptr; + // Don't do it if any of the terms are impure + for (AstNodeExpr* const exprp : exprps) { + if (!exprp->isPure()) return nullptr; + } + + // Construct the terms Vector that we are going to do processing on + std::vector terms(exprps.size() + 1); + // These are redundant (constructor does the same), but here they are for clarity + terms[0].offset = 0; + terms[exprps.size()].exprp = nullptr; + for (size_t i = 0; i < exprps.size(); ++i) { + terms[i].exprp = exprps[i]->unlinkFrBack(); + terms[i + 1].offset = terms[i].offset + exprps[i]->width(); + } + + // Round 1: try to create terms ending on VL_EDATASIZE boundaries. + // This ensures we pack bits within a VL_EDATASIZE first is possible, + // and then hopefully we can just assemble VL_EDATASIZE words afterward. + std::vector terms2; + { + terms2.reserve(terms.size()); + + size_t begin = 0; // Start of current range considered + size_t end = 0; // End of current range considered + size_t offset = 0; // Offset of current range considered + + // Create a term from the current range + const auto makeTerm = [&]() { + AstNodeExpr* const exprp = construct(terms, begin, end); + terms2.emplace_back(exprp, offset); + offset += exprp->width(); + begin = end; + }; + + // Create all terms ending on a boundary. + while (++end < terms.size() - 1) { + if (terms[end].offset % VL_EDATASIZE == 0) makeTerm(); + } + // Final term. Loop condition above ensures this always exists, + // and might or might not be on a boundary. + makeTerm(); + // Sentinel term + terms2.emplace_back(nullptr, offset); + // should have ended up with the same number of bits at least... + UASSERT(terms2.back().offset == terms.back().offset, "Inconsitent terms"); + } + + // Round 2: Combine the partial terms + return VN_AS(construct(terms2, 0, terms2.size() - 1), Concat); + } + +public: + static AstConcat* apply(AstConcat* rootp) { return balance(rootp); } +}; + class FuncOptVisitor final : public VNVisitor { // NODE STATE // AstNodeAssign::user() -> bool. Already checked, safe to split. Omit expensive check. + // AstConcat::user() -> bool. Already balanced. // STATE - Statistic tracking + VDouble0 m_balancedConcats; // Number of concatenations balanced VDouble0 m_concatSplits; // Number of splits in assignments with Concat on RHS // True for e.g.: foo = foo >> 1; or foo[foo[0]] = ...; @@ -142,18 +281,34 @@ class FuncOptVisitor final : public VNVisitor { void visit(AstNodeAssign* nodep) override { // TODO: Only thing remaining inside functions should be AstAssign (that is, an actual // assignment statemant), but we stil use AstAssignW, AstAssignDly, and all, fix. + iterateChildren(nodep); + if (v3Global.opt.fFuncSplitCat()) { if (splitConcat(nodep)) return; // Must return here, in case more code is added below } } - void visit(AstNodeExpr*) override {} // No need to descend further (Ignore AstExprStmt...) + void visit(AstConcat* nodep) override { + if (v3Global.opt.fFuncBalanceCat() && !nodep->user1() && !VN_IS(nodep->backp(), Concat)) { + if (AstConcat* const newp = BalanceConcatTree::apply(nodep)) { + UINFO(5, "balanceConcat optimizing " << nodep << "\n"); + ++m_balancedConcats; + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + newp->user1(true); // Must not attempt again. + // Return here. The new node will be iterated next. + return; + } + } + iterateChildren(nodep); + } void visit(AstNode* nodep) override { iterateChildren(nodep); } // CONSTRUCTORS explicit FuncOptVisitor(AstCFunc* funcp) { iterateChildren(funcp); } ~FuncOptVisitor() override { + V3Stats::addStatSum("Optimizations, FuncOpt concat trees balanced", m_balancedConcats); V3Stats::addStatSum("Optimizations, FuncOpt concat splits", m_concatSplits); } diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 11a154a43..c55af2780 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1305,7 +1305,9 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-fexpand", FOnOff, &m_fExpand); DECL_OPTION("-ffunc-opt", CbFOnOff, [this](bool flag) { // m_fFuncSplitCat = flag; + m_fFuncBalanceCat = flag; }); + DECL_OPTION("-ffunc-opt-balance-cat", FOnOff, &m_fFuncBalanceCat); DECL_OPTION("-ffunc-opt-split-cat", FOnOff, &m_fFuncSplitCat); DECL_OPTION("-fgate", FOnOff, &m_fGate); DECL_OPTION("-finline", FOnOff, &m_fInline); diff --git a/src/V3Options.h b/src/V3Options.h index 5eaa0aebd..67f66cd18 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -384,6 +384,7 @@ private: bool m_fDeadAssigns; // main switch: -fno-dead-assigns: remove dead assigns bool m_fDeadCells; // main switch: -fno-dead-cells: remove dead cells bool m_fExpand; // main switch: -fno-expand: expansion of C macros + bool m_fFuncBalanceCat = true; // main switch: -fno-func-balance-cat: expansion of C macros bool m_fFuncSplitCat = true; // main switch: -fno-func-split-cat: expansion of C macros bool m_fGate; // main switch: -fno-gate: gate wire elimination bool m_fInline; // main switch: -fno-inline: module inlining @@ -675,8 +676,9 @@ public: bool fDeadAssigns() const { return m_fDeadAssigns; } bool fDeadCells() const { return m_fDeadCells; } bool fExpand() const { return m_fExpand; } + bool fFuncBalanceCat() const { return m_fFuncBalanceCat; } bool fFuncSplitCat() const { return m_fFuncSplitCat; } - bool fFunc() const { return fFuncSplitCat(); } + bool fFunc() const { return fFuncSplitCat() || fFuncBalanceCat(); } bool fGate() const { return m_fGate; } bool fInline() const { return m_fInline; } bool fLife() const { return m_fLife; } diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 1c4d58cfa..1cfce8c30 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -287,7 +287,7 @@ static void process() { if (v3Global.opt.fDfgPreInline()) { // Pre inline DFG optimization - V3DfgOptimizer::optimize(v3Global.rootp(), "pre inline", /* lastInvocation: */ false); + V3DfgOptimizer::optimize(v3Global.rootp(), "pre inline"); } if (!(v3Global.opt.serializeOnly() && !v3Global.opt.flatten())) { @@ -304,7 +304,7 @@ static void process() { if (v3Global.opt.fDfgPostInline()) { // Post inline DFG optimization - V3DfgOptimizer::optimize(v3Global.rootp(), "post inline", /* lastInvocation: */ true); + V3DfgOptimizer::optimize(v3Global.rootp(), "post inline"); } // --PRE-FLAT OPTIMIZATIONS------------------ diff --git a/test_regress/t/t_dfg_balance_cats.py b/test_regress/t/t_balance_cats.py similarity index 55% rename from test_regress/t/t_dfg_balance_cats.py rename to test_regress/t/t_balance_cats.py index 93de94adf..b3cdbade4 100755 --- a/test_regress/t/t_dfg_balance_cats.py +++ b/test_regress/t/t_balance_cats.py @@ -13,12 +13,7 @@ test.scenarios('vlt') test.compile(verilator_flags2=["--stats"]) -test.file_grep(test.stats, - r' Optimizations, DFG pre inline BalanceTrees, concat trees balanced\s+(\d+)', 0) -test.file_grep(test.stats, - r' Optimizations, DFG post inline BalanceTrees, concat trees balanced\s+(\d+)', 1) -test.file_grep(test.stats, r'Optimizations, DFG pre inline Dfg2Ast, result equations\s+(\d+)', 1) -test.file_grep(test.stats, r'Optimizations, DFG post inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, FuncOpt concat trees balanced\s+(\d+)', 1) test.file_grep(test.stats, r'Optimizations, FuncOpt concat splits\s+(\d+)', 62) test.passes() diff --git a/test_regress/t/t_dfg_balance_cats.v b/test_regress/t/t_balance_cats.v similarity index 100% rename from test_regress/t/t_dfg_balance_cats.v rename to test_regress/t/t_balance_cats.v diff --git a/test_regress/t/t_dfg_balance_cats_nofunc.py b/test_regress/t/t_balance_cats_nofunc.py similarity index 53% rename from test_regress/t/t_dfg_balance_cats_nofunc.py rename to test_regress/t/t_balance_cats_nofunc.py index d57622f3a..6ce07d2c6 100755 --- a/test_regress/t/t_dfg_balance_cats_nofunc.py +++ b/test_regress/t/t_balance_cats_nofunc.py @@ -11,16 +11,11 @@ import vltest_bootstrap test.scenarios('vlt') -test.top_filename = "t/t_dfg_balance_cats.v" +test.top_filename = "t/t_balance_cats.v" test.compile(verilator_flags2=["--stats", "-fno-func-opt"]) -test.file_grep(test.stats, - r' Optimizations, DFG pre inline BalanceTrees, concat trees balanced\s+(\d+)', 0) -test.file_grep(test.stats, - r' Optimizations, DFG post inline BalanceTrees, concat trees balanced\s+(\d+)', 1) -test.file_grep(test.stats, r'Optimizations, DFG pre inline Dfg2Ast, result equations\s+(\d+)', 1) -test.file_grep(test.stats, r'Optimizations, DFG post inline Dfg2Ast, result equations\s+(\d+)', 1) +test.file_grep_not(test.stats, r'Optimizations, FuncOpt concat trees balances') test.file_grep_not(test.stats, r'Optimizations, FuncOpt concat splits') test.passes() diff --git a/test_regress/t/t_opt_const_dfg.py b/test_regress/t/t_opt_const_dfg.py index e46719f23..eed838d28 100755 --- a/test_regress/t/t_opt_const_dfg.py +++ b/test_regress/t/t_opt_const_dfg.py @@ -17,6 +17,6 @@ test.compile(verilator_flags2=["-Wno-UNOPTTHREADS", "--stats", test.t_dir + "/t_ test.execute() if test.vlt: - test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 39) + test.file_grep(test.stats, r'Optimizations, Const bit op reduction\s+(\d+)', 40) test.passes() From 863abdb1f767127eef307726e318c88e0518300e Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 10 Nov 2024 17:38:28 +0000 Subject: [PATCH 049/171] Fix NBAs to unpacked arrays of unpacked structs (#5603) This happened to work before #5516, by creating a whole shadow copy of the entire array. Revert back to that behaviour for now, it will be slow, but works still. Fixes #5590 --- src/V3Delayed.cpp | 11 +++- test_regress/t/t_nba_struct_array.py | 18 ++++++ test_regress/t/t_nba_struct_array.v | 93 ++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_nba_struct_array.py create mode 100644 test_regress/t/t_nba_struct_array.v diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 4d43665ec..31f21e5b2 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -251,10 +251,11 @@ class DelayedVisitor final : public VNVisitor { const AstNodeDType* const dtypep = vscp->dtypep()->skipRefp(); // Unpacked arrays if (const AstUnpackArrayDType* const uaDTypep = VN_CAST(dtypep, UnpackArrayDType)) { + // Basic underlying type of elements, if any. + AstBasicDType* const basicp = uaDTypep->basicp(); // If used in a loop, we must have a dynamic commit queue. (Also works in suspendables) if (vscpInfo.m_inLoop) { // Arrays with compound element types are currently not supported in loops - AstBasicDType* const basicp = uaDTypep->basicp(); if (!basicp || !(basicp->isIntegralOrPacked() // || basicp->isDouble() // @@ -266,8 +267,12 @@ class DelayedVisitor final : public VNVisitor { } // In a suspendable of fork, we must use the unique flag scheme, TODO: why? if (vscpInfo.m_inSuspOrFork) return Scheme::FlagUnique; - // Otherwise use the shared flag scheme - return Scheme::FlagShared; + // Otherwise if an array of packed/basic elements, use the shared flag scheme + if (basicp) return Scheme::FlagShared; + // Finally fall back on the shadow variable scheme, e.g. for + // arrays of unpacked structs. This will be slow. + // TODO: generic LHS scheme as discussed in #5092 + return Scheme::ShadowVar; } // In a suspendable of fork, we must use the unique flag scheme, TODO: why? diff --git a/test_regress/t/t_nba_struct_array.py b/test_regress/t/t_nba_struct_array.py new file mode 100755 index 000000000..f64ff6ad9 --- /dev/null +++ b/test_regress/t/t_nba_struct_array.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute(check_finished=True) + +test.passes() diff --git a/test_regress/t/t_nba_struct_array.v b/test_regress/t/t_nba_struct_array.v new file mode 100644 index 000000000..6233c3cf1 --- /dev/null +++ b/test_regress/t/t_nba_struct_array.v @@ -0,0 +1,93 @@ + +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0) + +module t(clk); + input clk; + + logic [31:0] cyc = 0; + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 99) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +`define at_posedge_clk_on_cycle(n) always @(posedge clk) if (cyc == n) + + struct { + int foo; + int bar; + } arr [2]; + + initial begin + arr[0].foo = 0; + arr[0].bar = 100; + arr[1].foo = 0; + arr[1].bar = 100; + end + + `at_posedge_clk_on_cycle(0) begin + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, 0); + `checkh(arr[i].bar, 100); + end + end + `at_posedge_clk_on_cycle(1) begin + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, 0); + `checkh(arr[i].bar, 100); + end + arr[0].foo <= 0; + arr[0].bar <= -0; + arr[1].foo <= 1; + arr[1].bar <= -1; + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, 0); + `checkh(arr[i].bar, 100); + end + end + `at_posedge_clk_on_cycle(2) begin + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, i); + `checkh(arr[i].bar, -i); + end + arr[0].foo <= ~0; + arr[0].bar <= 0; + arr[1].foo <= ~1; + arr[1].bar <= 1; + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, i); + `checkh(arr[i].bar, -i); + end + end + `at_posedge_clk_on_cycle(3) begin + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, ~i); + `checkh(arr[i].bar, i); + end + arr[0].foo <= -1; + arr[0].bar <= -2; + arr[1].foo <= -1; + arr[1].bar <= -2; + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, ~i); + `checkh(arr[i].bar, i); + end + end + `at_posedge_clk_on_cycle(4) begin + for (int i = 0; i < 2; ++i) begin + `checkh(arr[i].foo, -1); + `checkh(arr[i].bar, -2); + end + end + + +endmodule From 75e9986d3978ad032eb8072ed52144ed91c50fb1 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 15:27:13 -0500 Subject: [PATCH 050/171] Fix local:: mis-allowed in `class extends` --- src/V3LinkDot.cpp | 27 +++++++++++++------------- src/verilog.y | 6 ------ test_regress/t/t_package_local_bad.out | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 1e14a5d04..29ebd6a47 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2143,7 +2143,7 @@ class LinkDotResolveVisitor final : public VNVisitor { VSymEnt* m_curSymp = nullptr; // SymEnt for current lookup point VSymEnt* m_modSymp = nullptr; // SymEnt for current module VSymEnt* m_pinSymp = nullptr; // SymEnt for pin lookups - VSymEnt* m_fromSymp = nullptr; // SymEnt for randomize lookups + VSymEnt* m_randSymp = nullptr; // SymEnt for randomize target class's lookups const AstCell* m_cellp = nullptr; // Current cell AstNodeModule* m_modp = nullptr; // Current module AstNodeFTask* m_ftaskp = nullptr; // Current function/task @@ -2599,7 +2599,7 @@ class LinkDotResolveVisitor final : public VNVisitor { UINFO(8, indent() << m_ds.ascii() << endl); const DotStates lastStates = m_ds; const bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed - VL_RESTORER(m_fromSymp); + VL_RESTORER(m_randSymp); { if (start) { // Starting dot sequence if (debug() >= 9) nodep->dumpTree("- dot-in: "); @@ -2795,7 +2795,7 @@ class LinkDotResolveVisitor final : public VNVisitor { classOrPackagep = cpackagerefp->classOrPackagep(); UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); if (cpackagerefp->name() == "local::") { - m_fromSymp = nullptr; + m_randSymp = nullptr; first = true; } else { m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); @@ -2818,8 +2818,8 @@ class LinkDotResolveVisitor final : public VNVisitor { VSymEnt* foundp; string baddot; VSymEnt* okSymp = nullptr; - if (m_fromSymp) { - foundp = m_fromSymp->findIdFlat(nodep->name()); + if (m_randSymp) { + foundp = m_randSymp->findIdFlat(nodep->name()); if (foundp) { if (!start) m_ds.m_dotPos = DP_MEMBER; if (!m_inWith) { @@ -3165,8 +3165,9 @@ class LinkDotResolveVisitor final : public VNVisitor { iterateChildren(nodep); if (nodep->name() == "local::") { - if (!m_fromSymp) { - nodep->v3error("Illegal 'local::' outside 'randomize() with'"); + if (!m_randSymp) { + nodep->v3error("Illegal 'local::' outside 'randomize() with'" + " (IEEE 1800-2023 18.7.1)"); m_ds.m_dotErr = true; } } @@ -3325,7 +3326,7 @@ class LinkDotResolveVisitor final : public VNVisitor { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); VL_RESTORER(m_ds); - VL_RESTORER(m_fromSymp); + VL_RESTORER(m_randSymp); VL_RESTORER(m_randMethodCallp); { m_ds.init(m_curSymp); @@ -3368,7 +3369,7 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep->v3error("'randomize() with' on a non-class-instance " << fromDtp->prettyNameQ()); else - m_fromSymp = m_statep->getNodeSym(classDtp->classp()); + m_randSymp = m_statep->getNodeSym(classDtp->classp()); } } iterateChildren(nodep); @@ -3404,7 +3405,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } } - VL_RESTORER(m_fromSymp); + VL_RESTORER(m_randSymp); bool first = !m_ds.m_dotp || m_ds.m_dotPos == DP_FIRST; bool staticAccess = false; @@ -3428,7 +3429,7 @@ class LinkDotResolveVisitor final : public VNVisitor { = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); if (cpackagerefp->name() == "local::") { - m_fromSymp = nullptr; + m_randSymp = nullptr; first = true; } else { nodep->classOrPackagep(cpackagerefp->classOrPackagep()); @@ -3500,8 +3501,8 @@ class LinkDotResolveVisitor final : public VNVisitor { dotSymp = m_statep->findDotted(nodep->fileline(), dotSymp, nodep->dotted(), baddot, okSymp, true); // Maybe nullptr } - if (m_fromSymp) { - VSymEnt* const foundp = m_fromSymp->findIdFlat(nodep->name()); + if (m_randSymp) { + VSymEnt* const foundp = m_randSymp->findIdFlat(nodep->name()); if (foundp && m_inWith) { UINFO(9, indent() << "randomize-with fromSym " << foundp->nodep() << endl); AstNodeExpr* argsp = nullptr; diff --git a/src/verilog.y b/src/verilog.y index 6129562ef..067405e47 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7240,12 +7240,6 @@ class_typeExtImpOne: // part of IEEE: class_type, where we either ge { $$ = new AstClassOrPackageRef{$1, "$unit", nullptr, nullptr}; $$ = nullptr; // No purpose otherwise, every symtab can see root SYMP->nextId(PARSEP->rootp()); } - // - | yLOCAL__COLONCOLON yP_COLONCOLON - { $$ = new AstClassOrPackageRef{$1, "local::", nullptr, nullptr}; - $$ = nullptr; // UNSUP - SYMP->nextId(PARSEP->rootp()); - BBUNSUP($1, "Unsupported: Randomize 'local::'"); } ; //========= diff --git a/test_regress/t/t_package_local_bad.out b/test_regress/t/t_package_local_bad.out index 8cad1cb2e..e219c46a2 100644 --- a/test_regress/t/t_package_local_bad.out +++ b/test_regress/t/t_package_local_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_package_local_bad.v:9:16: Illegal 'local::' outside 'randomize() with' +%Error: t/t_package_local_bad.v:9:16: Illegal 'local::' outside 'randomize() with' (IEEE 1800-2023 18.7.1) 9 | $display(local::x); | ^~~~~ %Error: t/t_package_local_bad.v:9:23: Can't find definition of scope/variable/func: 'x' From 873048c21cb258dedd753123c7f6ab528b5bbea6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 16:51:34 -0500 Subject: [PATCH 051/171] Fix 'local::' parsing in wrong scope --- src/V3LinkDot.cpp | 7 ++++--- src/verilog.y | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 29ebd6a47..1ea0d79f2 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2792,12 +2792,12 @@ class LinkDotResolveVisitor final : public VNVisitor { "Bad package link"); AstClassOrPackageRef* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); - classOrPackagep = cpackagerefp->classOrPackagep(); - UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; } else { + classOrPackagep = cpackagerefp->classOrPackagep(); + UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); } m_ds.m_dotPos = DP_SCOPE; @@ -3169,6 +3169,7 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep->v3error("Illegal 'local::' outside 'randomize() with'" " (IEEE 1800-2023 18.7.1)"); m_ds.m_dotErr = true; + return; } } AstClass* const modClassp = VN_CAST(m_modp, Class); @@ -3427,11 +3428,11 @@ class LinkDotResolveVisitor final : public VNVisitor { staticAccess = true; AstClassOrPackageRef* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); - UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; } else { + UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); nodep->classOrPackagep(cpackagerefp->classOrPackagep()); } // Class/package :: HERE function() . method_called_on_function_return_value() diff --git a/src/verilog.y b/src/verilog.y index 067405e47..8e2373723 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7311,13 +7311,13 @@ dollarUnitNextId: // $unit SYMP->nextId(PARSEP->rootp()); } ; -localNextId: // local +localNextId: // local:: // // IMPORTANT: The lexer will parse the following ID to be in the found package // // if not needed must use packageClassScopeNoId // // Must call nextId without any additional tokens following yLOCAL__COLONCOLON - { $$ = new AstClassOrPackageRef{$1, "local::", PARSEP->unitPackage($1), nullptr}; - SYMP->nextId(PARSEP->rootp()); } + { $$ = new AstClassOrPackageRef{$1, "local::", nullptr, nullptr}; + /* No SYMP->nextId(...); normal search upward we should find local's vars */ } ; //^^^========= From b74a8f133fd476af25aa8ca2e26b3dbf930653be Mon Sep 17 00:00:00 2001 From: github action Date: Sun, 10 Nov 2024 21:54:54 +0000 Subject: [PATCH 052/171] Apply 'make format' --- src/V3LinkDot.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 1ea0d79f2..f1759de79 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3432,7 +3432,8 @@ class LinkDotResolveVisitor final : public VNVisitor { m_randSymp = nullptr; first = true; } else { - UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); + UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), + "Bad package link"); nodep->classOrPackagep(cpackagerefp->classOrPackagep()); } // Class/package :: HERE function() . method_called_on_function_return_value() From c3b2bfbc392abdf2a70a6154e5a167c3e673b0a6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 17:37:08 -0500 Subject: [PATCH 053/171] Internals: Fix missing cleanFileline --- src/V3LinkParse.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 69a5d2c2e..766eaabbd 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -816,9 +816,6 @@ class LinkParseVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } - void visit(AstClassOrPackageRef* nodep) override { // - iterateChildren(nodep); - } void visit(AstClocking* nodep) override { cleanFileline(nodep); VL_RESTORER(m_defaultInSkewp); From b71d49e55ab66c32fae10b9f5a71a9e36921734c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 18:27:14 -0500 Subject: [PATCH 054/171] Internals: Defer `$unit` package resolution until link --- src/V3LinkDot.cpp | 7 +++++++ src/verilog.y | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index f1759de79..bb842f9dd 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1011,6 +1011,12 @@ class LinkDotFindVisitor final : public VNVisitor { if (!m_explicitNew && m_statep->forPrimary()) makeImplicitNew(nodep); } } + void visit(AstClassOrPackageRef* nodep) override { + if (!nodep->classOrPackageNodep() && nodep->name() == "$unit") { + nodep->classOrPackageNodep(v3Global.rootp()->dollarUnitPkgAddp()); + } + iterateChildren(nodep); + } void visit(AstScope* nodep) override { UASSERT_OBJ(m_statep->forScopeCreation(), nodep, "Scopes should only exist right after V3Scope"); @@ -3806,6 +3812,7 @@ class LinkDotResolveVisitor final : public VNVisitor { if (AstClassOrPackageRef* lookNodep = VN_CAST(dotp->lhsp(), ClassOrPackageRef)) { iterate(lookNodep); cprp = dotp->rhsp(); + UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link"); lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep()); } else { dotp->lhsp()->v3error("Attempting to extend" // LCOV_EXCL_LINE diff --git a/src/verilog.y b/src/verilog.y index 8e2373723..d795dd611 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7307,7 +7307,7 @@ dollarUnitNextId: // $unit // // if not needed must use packageClassScopeNoId // // Must call nextId without any additional tokens following yD_UNIT - { $$ = new AstClassOrPackageRef{$1, "$unit", PARSEP->unitPackage($1), nullptr}; + { $$ = new AstClassOrPackageRef{$1, "$unit", nullptr, nullptr}; SYMP->nextId(PARSEP->rootp()); } ; From 15d1751b23097af47ddd2a92531b173c04d11af8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 19:34:00 -0500 Subject: [PATCH 055/171] Internals: Defer `class extends` resolution until link --- src/V3LinkDot.cpp | 35 ++++++++++++++++++----- src/verilog.y | 4 +-- test_regress/t/t_class_extends_nf_bad.out | 8 ++++-- test_regress/t/t_class_extends_nf_bad.v | 10 ++++++- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index bb842f9dd..7471e755e 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -84,6 +84,12 @@ class LinkNodeMatcherClass final : public VNodeMatcher { public: bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Class); } }; +class LinkNodeMatcherClassOrPackage final : public VNodeMatcher { +public: + bool nodeMatch(const AstNode* nodep) const override { + return VN_IS(nodep, Class) || VN_IS(nodep, Package); + } +}; class LinkNodeMatcherFTask final : public VNodeMatcher { public: bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, NodeFTask); } @@ -2300,6 +2306,23 @@ class LinkDotResolveVisitor final : public VNVisitor { UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName); return ifaceTopVarp; } + VSymEnt* findClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool classOnly, + const string& forWhat) { + if (nodep->classOrPackagep()) return m_statep->getNodeSym(nodep->classOrPackagep()); + VSymEnt* const foundp = lookSymp->findIdFallback(nodep->name()); + if (foundp) { + nodep->classOrPackageNodep(foundp->nodep()); + return foundp; + } else { + const string suggest = m_statep->suggestSymFallback(lookSymp, nodep->name(), + LinkNodeMatcherClassOrPackage{}); + nodep->v3error((classOnly ? "Class" : "Package/Class") + << " for '" << forWhat // extends/implements + << "' not found: " << nodep->prettyNameQ() << '\n' + << (suggest.empty() ? "" : nodep->warnMore() + suggest)); + return nullptr; + } + } void markAndCheckPinDup(AstPin* nodep, AstNode* refp, const char* whatp) { const auto pair = m_usedPins.emplace(refp, nodep); if (!pair.second) { @@ -3812,6 +3835,9 @@ class LinkDotResolveVisitor final : public VNVisitor { if (AstClassOrPackageRef* lookNodep = VN_CAST(dotp->lhsp(), ClassOrPackageRef)) { iterate(lookNodep); cprp = dotp->rhsp(); + VSymEnt* const foundp + = findClassOrPackage(lookSymp, lookNodep, false, nodep->verilogKwd()); + if (!foundp) return; UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link"); lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep()); } else { @@ -3825,7 +3851,8 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep->v3error("Attempting to extend using non-class"); // LCOV_EXCL_LINE return; } - VSymEnt* const foundp = lookSymp->findIdFallback(cpackagerefp->name()); + VSymEnt* const foundp + = findClassOrPackage(lookSymp, cpackagerefp, true, nodep->verilogKwd()); if (foundp) { if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) { AstPin* paramsp = cpackagerefp->paramsp(); @@ -3850,12 +3877,6 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } } else { - const string suggest = m_statep->suggestSymFallback( - m_curSymp, cpackagerefp->name(), LinkNodeMatcherClass{}); - cpackagerefp->v3error( - "Class for '" << nodep->verilogKwd() // extends/implements - << "' not found: " << cpackagerefp->prettyNameQ() << '\n' - << (suggest.empty() ? "" : cpackagerefp->warnMore() + suggest)); return; } if (!nodep->childDTypep()) nodep->v3error("Attempting to extend using non-class"); diff --git a/src/verilog.y b/src/verilog.y index d795dd611..9854644fd 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7227,12 +7227,12 @@ class_typeExtImpOne: // part of IEEE: class_type, where we either ge idAny /*mid*/ { /* no nextId as not refing it above this*/ } /*cont*/ parameter_value_assignmentClassE - { $$ = new AstClassOrPackageRef{$1, *$1, $1, $3}; + { $$ = new AstClassOrPackageRef{$1, *$1, nullptr, $3}; $$ = $1; } | idCC /*mid*/ { /* no nextId as not refing it above this*/ } /*cont*/ parameter_value_assignmentClassE - { $$ = new AstClassOrPackageRef{$1, *$1, $1, $3}; + { $$ = new AstClassOrPackageRef{$1, *$1, nullptr, $3}; $$ = $1; } // // // package_sopeIdFollows expanded diff --git a/test_regress/t/t_class_extends_nf_bad.out b/test_regress/t/t_class_extends_nf_bad.out index d01cc3eea..b0aac0bf5 100644 --- a/test_regress/t/t_class_extends_nf_bad.out +++ b/test_regress/t/t_class_extends_nf_bad.out @@ -1,5 +1,9 @@ -%Error: t/t_class_extends_nf_bad.v:10:19: Class for 'extends' not found: 'IsNotFound' +%Error: t/t_class_extends_nf_bad.v:15:19: Class for 'extends' not found: 'IsNotFound' : ... Suggested alternative: 'IsFound' - 10 | class Cls extends IsNotFound; + 15 | class Cls extends IsNotFound; | ^~~~~~~~~~ +%Error: t/t_class_extends_nf_bad.v:18:25: Class for 'extends' not found: 'NotFound2' + : ... Suggested alternative: 'otFound2' + 18 | class Cls2 extends Pkg::NotFound2; + | ^~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_extends_nf_bad.v b/test_regress/t/t_class_extends_nf_bad.v index 2285ba8e6..533887e56 100644 --- a/test_regress/t/t_class_extends_nf_bad.v +++ b/test_regress/t/t_class_extends_nf_bad.v @@ -4,10 +4,18 @@ // any use, without warranty, 2020 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +package Pkg; +class otFound2; +endclass +endpackage + class IsFound; endclass -class Cls extends IsNotFound; +class Cls extends IsNotFound; // BAD: not found +endclass + +class Cls2 extends Pkg::NotFound2; // BAD: not found endclass module t (/*AUTOARG*/); From 151c5b6a1d22c1b2421d255f4f16f3ec97ab0760 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 10 Nov 2024 20:00:16 -0500 Subject: [PATCH 056/171] Tests: Rename some tests --- .../t/{t_f_bad.out => t_flag_f_bad.out} | 0 .../t/{t_f_bad.py => t_flag_f_bad.py} | 0 test_regress/t/t_package_identifier_bad.out | 5 +++++ ...ier_bad.py => t_package_identifier_bad.py} | 0 ...ifier_bad.v => t_package_identifier_bad.v} | 6 +++--- ...tems.py => t_package_using_dollar_unit.py} | 0 ..._items.v => t_package_using_dollar_unit.v} | 0 test_regress/t/t_pkg_identifier_bad.out | 5 ----- ..._assign_sbw.cpp => t_sc_vl_assign_sbw.cpp} | 0 ...vl_assign_sbw.py => t_sc_vl_assign_sbw.py} | 0 ...t_vl_assign_sbw.v => t_sc_vl_assign_sbw.v} | 0 ...e_deep.py => t_timing_suspendable_deep.py} | 0 ...ble_deep.v => t_timing_suspendable_deep.v} | 0 ...waivers.py => t_waiveroutput_multiline.py} | 0 ...e_waivers.v => t_waiveroutput_multiline.v} | 0 test_regress/t/t_width_docs_bad.v | 19 ------------------- 16 files changed, 8 insertions(+), 27 deletions(-) rename test_regress/t/{t_f_bad.out => t_flag_f_bad.out} (100%) rename test_regress/t/{t_f_bad.py => t_flag_f_bad.py} (100%) create mode 100644 test_regress/t/t_package_identifier_bad.out rename test_regress/t/{t_pkg_identifier_bad.py => t_package_identifier_bad.py} (100%) rename test_regress/t/{t_pkg_identifier_bad.v => t_package_identifier_bad.v} (83%) rename test_regress/t/{t_pkg_using_dollar_unit_items.py => t_package_using_dollar_unit.py} (100%) rename test_regress/t/{t_pkg_using_dollar_unit_items.v => t_package_using_dollar_unit.v} (100%) delete mode 100644 test_regress/t/t_pkg_identifier_bad.out rename test_regress/t/{t_vl_assign_sbw.cpp => t_sc_vl_assign_sbw.cpp} (100%) rename test_regress/t/{t_vl_assign_sbw.py => t_sc_vl_assign_sbw.py} (100%) rename test_regress/t/{t_vl_assign_sbw.v => t_sc_vl_assign_sbw.v} (100%) rename test_regress/t/{t_suspendable_deep.py => t_timing_suspendable_deep.py} (100%) rename test_regress/t/{t_suspendable_deep.v => t_timing_suspendable_deep.v} (100%) rename test_regress/t/{t_multiline_waivers.py => t_waiveroutput_multiline.py} (100%) rename test_regress/t/{t_multiline_waivers.v => t_waiveroutput_multiline.v} (100%) delete mode 100644 test_regress/t/t_width_docs_bad.v diff --git a/test_regress/t/t_f_bad.out b/test_regress/t/t_flag_f_bad.out similarity index 100% rename from test_regress/t/t_f_bad.out rename to test_regress/t/t_flag_f_bad.out diff --git a/test_regress/t/t_f_bad.py b/test_regress/t/t_flag_f_bad.py similarity index 100% rename from test_regress/t/t_f_bad.py rename to test_regress/t/t_flag_f_bad.py diff --git a/test_regress/t/t_package_identifier_bad.out b/test_regress/t/t_package_identifier_bad.out new file mode 100644 index 000000000..6097d0e73 --- /dev/null +++ b/test_regress/t/t_package_identifier_bad.out @@ -0,0 +1,5 @@ +%Error-PKGNODECL: t/t_package_identifier_bad.v:15:20: Package/class 'Bar' not found, and needs to be predeclared (IEEE 1800-2023 26.3) + 15 | int baz = Foo::Bar::baz; + | ^~~ + ... For error description see https://verilator.org/warn/PKGNODECL?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_pkg_identifier_bad.py b/test_regress/t/t_package_identifier_bad.py similarity index 100% rename from test_regress/t/t_pkg_identifier_bad.py rename to test_regress/t/t_package_identifier_bad.py diff --git a/test_regress/t/t_pkg_identifier_bad.v b/test_regress/t/t_package_identifier_bad.v similarity index 83% rename from test_regress/t/t_pkg_identifier_bad.v rename to test_regress/t/t_package_identifier_bad.v index a3cd4a068..a3457cee5 100644 --- a/test_regress/t/t_pkg_identifier_bad.v +++ b/test_regress/t/t_package_identifier_bad.v @@ -4,13 +4,13 @@ // any use, without warranty, 2023 by Antmicro Ltd. // SPDX-License-Identifier: CC0-1.0 -package foo; +package Foo; endpackage -package bar; +package Bar; static int baz; endpackage module t; - int baz = foo::bar::baz; + int baz = Foo::Bar::baz; endmodule diff --git a/test_regress/t/t_pkg_using_dollar_unit_items.py b/test_regress/t/t_package_using_dollar_unit.py similarity index 100% rename from test_regress/t/t_pkg_using_dollar_unit_items.py rename to test_regress/t/t_package_using_dollar_unit.py diff --git a/test_regress/t/t_pkg_using_dollar_unit_items.v b/test_regress/t/t_package_using_dollar_unit.v similarity index 100% rename from test_regress/t/t_pkg_using_dollar_unit_items.v rename to test_regress/t/t_package_using_dollar_unit.v diff --git a/test_regress/t/t_pkg_identifier_bad.out b/test_regress/t/t_pkg_identifier_bad.out deleted file mode 100644 index b05993a11..000000000 --- a/test_regress/t/t_pkg_identifier_bad.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error-PKGNODECL: t/t_pkg_identifier_bad.v:15:20: Package/class 'bar' not found, and needs to be predeclared (IEEE 1800-2023 26.3) - 15 | int baz = foo::bar::baz; - | ^~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest -%Error: Exiting due to diff --git a/test_regress/t/t_vl_assign_sbw.cpp b/test_regress/t/t_sc_vl_assign_sbw.cpp similarity index 100% rename from test_regress/t/t_vl_assign_sbw.cpp rename to test_regress/t/t_sc_vl_assign_sbw.cpp diff --git a/test_regress/t/t_vl_assign_sbw.py b/test_regress/t/t_sc_vl_assign_sbw.py similarity index 100% rename from test_regress/t/t_vl_assign_sbw.py rename to test_regress/t/t_sc_vl_assign_sbw.py diff --git a/test_regress/t/t_vl_assign_sbw.v b/test_regress/t/t_sc_vl_assign_sbw.v similarity index 100% rename from test_regress/t/t_vl_assign_sbw.v rename to test_regress/t/t_sc_vl_assign_sbw.v diff --git a/test_regress/t/t_suspendable_deep.py b/test_regress/t/t_timing_suspendable_deep.py similarity index 100% rename from test_regress/t/t_suspendable_deep.py rename to test_regress/t/t_timing_suspendable_deep.py diff --git a/test_regress/t/t_suspendable_deep.v b/test_regress/t/t_timing_suspendable_deep.v similarity index 100% rename from test_regress/t/t_suspendable_deep.v rename to test_regress/t/t_timing_suspendable_deep.v diff --git a/test_regress/t/t_multiline_waivers.py b/test_regress/t/t_waiveroutput_multiline.py similarity index 100% rename from test_regress/t/t_multiline_waivers.py rename to test_regress/t/t_waiveroutput_multiline.py diff --git a/test_regress/t/t_multiline_waivers.v b/test_regress/t/t_waiveroutput_multiline.v similarity index 100% rename from test_regress/t/t_multiline_waivers.v rename to test_regress/t/t_waiveroutput_multiline.v diff --git a/test_regress/t/t_width_docs_bad.v b/test_regress/t/t_width_docs_bad.v deleted file mode 100644 index 13ed51756..000000000 --- a/test_regress/t/t_width_docs_bad.v +++ /dev/null @@ -1,19 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2009 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -module t; - int array[5]; - bit [1:0] rd_addr; - wire int rd_value = read_array[rd_addr]; //<--- Warning - - ok ok(); -endmodule - -module ok; - int array[5]; - bit [1:0] rd_addr; - wire int rd_value = read_array[{1'b0, rd_addr}]; //<--- Fixed -endmodule; From 7c8ff1d19c79400d0e0d5abb3adc7c6e404b120d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 08:30:07 -0500 Subject: [PATCH 057/171] Add `--no-std-package` as subset-alias of `--no-std`. --- Changes | 1 + bin/verilator | 3 ++- docs/guide/exe_verilator.rst | 8 +++++++- src/V3Global.cpp | 2 +- src/V3Options.cpp | 5 +++-- src/V3Options.h | 4 ++-- test_regress/t/t_no_std_pkg_bad.py | 20 ++++++++++++++++++++ 7 files changed, 36 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_no_std_pkg_bad.py diff --git a/Changes b/Changes index a5effd1d4..c958b258a 100644 --- a/Changes +++ b/Changes @@ -16,6 +16,7 @@ Verilator 5.031 devel * Support queue's assignment `push_back/push_front('{})` (#5585) (#5586). [Yilou Wang] * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] * Support `pure constraint`. +* Add `--no-std-package` as subset-alias of `--no-std`. * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] diff --git a/bin/verilator b/bin/verilator index 1ca6d3b8c..fea7d9008 100755 --- a/bin/verilator +++ b/bin/verilator @@ -448,7 +448,8 @@ detailed descriptions of these arguments. --no-skip-identical Disable skipping identical output --stats Create statistics file --stats-vars Provide statistics on variables - --no-std Prevent parsing standard library + --no-std Prevent loading standard files + --no-std-package Prevent parsing standard package --no-stop-fail Do not call $stop when assertion fails --structs-packed Convert all unpacked structures to packed structures -sv Enable SystemVerilog parsing diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 1ec0efd4e..d6b979c81 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1363,7 +1363,13 @@ Summary: .. option:: --no-std - Prevents parsing standard library. + Prevents parsing standard input files, alias for + :opt:`--no-std-package`. This may be extended to prevent reading other + standardized files in future versions. + +.. option:: --no-std-package + + Prevents parsing standard `std::` package file. .. option:: --no-stop-fail diff --git a/src/V3Global.cpp b/src/V3Global.cpp index bb4170898..924a664e1 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -66,7 +66,7 @@ void V3Global::readFiles() { } // Parse the std package - if (v3Global.opt.std()) { + if (v3Global.opt.stdPackage()) { parser.parseFile(new FileLine{V3Options::getStdPackagePath()}, V3Options::getStdPackagePath(), false, "Cannot find verilated_std.sv containing built-in std:: definitions: "); diff --git a/src/V3Options.cpp b/src/V3Options.cpp index c55af2780..6d59c99d1 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1258,7 +1258,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-json-edit-nums", OnOff, &m_jsonEditNums); DECL_OPTION("-json-ids", OnOff, &m_jsonIds); DECL_OPTION("-E", CbOnOff, [this](bool flag) { - if (flag) m_std = false; + if (flag) m_stdPackage = false; m_preprocOnly = flag; }); DECL_OPTION("-emit-accessors", OnOff, &m_emitAccessors); @@ -1512,7 +1512,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, m_statsVars = flag; m_stats |= flag; }); - DECL_OPTION("-std", OnOff, &m_std); + DECL_OPTION("-std", CbOnOff, [this](bool flag) { m_stdPackage = flag; }); + DECL_OPTION("-std-package", OnOff, &m_stdPackage); DECL_OPTION("-stop-fail", OnOff, &m_stopFail); DECL_OPTION("-structs-packed", OnOff, &m_structsPacked); DECL_OPTION("-sv", CbCall, [this]() { m_defaultLanguage = V3LangCode::L1800_2023; }); diff --git a/src/V3Options.h b/src/V3Options.h index 67f66cd18..74de94871 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -279,7 +279,7 @@ private: bool m_relativeIncludes = false; // main switch: --relative-includes bool m_reportUnoptflat = false; // main switch: --report-unoptflat bool m_savable = false; // main switch: --savable - bool m_std = true; // main switch: --std + bool m_stdPackage = true; // main switch: --std-package bool m_structsPacked = false; // main switch: --structs-packed bool m_systemC = false; // main switch: --sc: System C instead of simple C++ bool m_stats = false; // main switch: --stats @@ -465,7 +465,7 @@ public: bool savable() const VL_MT_SAFE { return m_savable; } bool stats() const { return m_stats; } bool statsVars() const { return m_statsVars; } - bool std() const { return m_std; } + bool stdPackage() const { return m_stdPackage; } bool structsPacked() const { return m_structsPacked; } bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined bool assertCaseOn() const { return m_assertCase || m_assert; } diff --git a/test_regress/t/t_no_std_pkg_bad.py b/test_regress/t/t_no_std_pkg_bad.py new file mode 100755 index 000000000..84dacb568 --- /dev/null +++ b/test_regress/t/t_no_std_pkg_bad.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = "t/t_no_std_bad.v" +test.golden_filename = "t/t_no_std_bad.out" + +test.lint(fails=True, + verilator_flags2=["--no-std-package", "--exe --main --timing -Wall"], + expect_filename=test.golden_filename) + +test.passes() From 3c686d0eb207f702360ce5be18a41c51fb23ba0f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 08:44:46 -0500 Subject: [PATCH 058/171] Commentary --- docs/internals.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/internals.rst b/docs/internals.rst index 0bea6adc7..39a01048e 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -1656,7 +1656,7 @@ field in the section below. +---------------+--------------------------------------------------------+ | ``1:2:`` | The hierarchy of the ``VAR`` is the ``op2p`` | | | pointer under the ``MODULE``, which in turn is the | -| | ``op1p`` pointer under the ``NETLIST`` | +| | ``op1p`` pointer under the ``NETLIST``. | +---------------+--------------------------------------------------------+ | ``VAR`` | The AstNodeType (e.g. ``AstVar``). | +---------------+--------------------------------------------------------+ @@ -1670,7 +1670,7 @@ field in the section below. | | and "aa" the 27th. Then line 22 in that file, then | | | column 8 (aa=0, az=25, ba=26, ...). | +---------------+--------------------------------------------------------+ -| ``@dt=0x...`` | The address of the data type this node contains. | +| ``@dt=0x...`` | The address of the data type this node references. | +---------------+--------------------------------------------------------+ | ``w32`` | The data-type width() is 32 bits. | +---------------+--------------------------------------------------------+ @@ -1678,7 +1678,7 @@ field in the section below. | | variable. | +---------------+--------------------------------------------------------+ | ``[O]`` | Flags which vary with the type of node, in this | -| | case, it means the variable is an output. | +| | case of a VAR, it means the variable is an output. | +---------------+--------------------------------------------------------+ In more detail, the following fields are dumped common to all nodes. They From 46a5f048406080bf27c55d29546804d6c2aea474 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 09:36:36 -0500 Subject: [PATCH 059/171] Internals: Link 'std' in LinkFind --- src/V3LinkDot.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 7471e755e..5923fce82 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1018,8 +1018,12 @@ class LinkDotFindVisitor final : public VNVisitor { } } void visit(AstClassOrPackageRef* nodep) override { - if (!nodep->classOrPackageNodep() && nodep->name() == "$unit") { - nodep->classOrPackageNodep(v3Global.rootp()->dollarUnitPkgAddp()); + if (!nodep->classOrPackageNodep()) { + if (nodep->name() == "$unit") { + nodep->classOrPackageNodep(v3Global.rootp()->dollarUnitPkgAddp()); + } else if (nodep->name() == "std") { + nodep->classOrPackageNodep(v3Global.rootp()->stdPackagep()); + } } iterateChildren(nodep); } @@ -2202,7 +2206,6 @@ class LinkDotResolveVisitor final : public VNVisitor { sstr << "ds=" << names[m_dotPos]; sstr << " dse" << cvtToHex(m_dotSymp); sstr << "(" << m_dotSymp->nodep()->typeName() << ")"; - if (m_dotErr) sstr << " [dotErr]"; if (m_super) sstr << " [super]"; if (m_unresolvedCell) sstr << " [unrCell]"; @@ -2698,6 +2701,7 @@ class LinkDotResolveVisitor final : public VNVisitor { // DOT(DOT(x,*here*),real-rhs) which we consider a RHS if (start && m_ds.m_dotPos == DP_SCOPE) m_ds.m_dotPos = DP_FINAL; UINFO(8, indent() << "iter.rhs " << m_ds.ascii() << " " << nodep << endl); + // m_ds.m_dotSymp points at lhsp()'s symbol table, so resolve RHS under that iterateAndNextNull(nodep->rhsp()); UINFO(8, indent() << "iter.rdone " << m_ds.ascii() << " " << nodep << endl); // if (debug() >= 9) nodep->dumpTree("- dot-rho: "); @@ -3178,9 +3182,6 @@ class LinkDotResolveVisitor final : public VNVisitor { VL_RESTORER(m_ds); VL_RESTORER(m_pinSymp); - if (nodep->name() == "std" && !nodep->classOrPackagep()) { - nodep->classOrPackagep(v3Global.rootp()->stdPackagep()); - } // ClassRef's have pins, so track if (nodep->classOrPackagep()) { m_pinSymp = m_statep->getNodeSym(nodep->classOrPackagep()); From 4d95f6f7b8052ca47a8eba10b3a9507d83dc439a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 20:00:26 -0500 Subject: [PATCH 060/171] Add `--waiver-multiline` for context-sensitive `--waiver-output`. --- Changes | 1 + bin/verilator | 3 +- docs/guide/exe_verilator.rst | 9 ++++ src/V3Ast.cpp | 13 ++--- src/V3Config.cpp | 6 ++- src/V3Error.cpp | 2 + src/V3FileLine.cpp | 34 ++++++++---- src/V3Options.cpp | 1 + src/V3Options.h | 2 + src/V3Waiver.cpp | 53 ++++++++++++++++--- src/V3Waiver.h | 2 +- test_regress/t/t_waiveroutput.out | 9 ++-- test_regress/t/t_waiveroutput.py | 2 +- test_regress/t/t_waiveroutput_allgood.out | 6 +-- test_regress/t/t_waiveroutput_allgood.py | 4 +- test_regress/t/t_waiveroutput_allgood.vlt | 11 ---- test_regress/t/t_waiveroutput_multiline.out | 11 ++++ test_regress/t/t_waiveroutput_multiline.py | 14 ++--- ...ut_wall.py => t_waiveroutput_roundtrip.py} | 10 ++-- ...multiline.v => t_waiveroutput_roundtrip.v} | 0 test_regress/t/t_waiveroutput_wall.out | 10 ---- test_regress/t/t_waiveroutput_wall.vlt | 11 ---- 22 files changed, 133 insertions(+), 81 deletions(-) delete mode 100644 test_regress/t/t_waiveroutput_allgood.vlt create mode 100644 test_regress/t/t_waiveroutput_multiline.out rename test_regress/t/{t_waiveroutput_wall.py => t_waiveroutput_roundtrip.py} (63%) rename test_regress/t/{t_waiveroutput_multiline.v => t_waiveroutput_roundtrip.v} (100%) delete mode 100644 test_regress/t/t_waiveroutput_wall.out delete mode 100644 test_regress/t/t_waiveroutput_wall.vlt diff --git a/Changes b/Changes index c958b258a..ea35c34c9 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,7 @@ Verilator 5.031 devel * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] * Support `pure constraint`. * Add `--no-std-package` as subset-alias of `--no-std`. +* Add `--waiver-multiline` for context-sensitive `--waiver-output`. * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] diff --git a/bin/verilator b/bin/verilator index fea7d9008..28acbbcf6 100755 --- a/bin/verilator +++ b/bin/verilator @@ -488,7 +488,8 @@ detailed descriptions of these arguments. +verilog2001ext+ Synonym for +1364-2001ext+ --version Show program version and exits --vpi Enable VPI compiles - --waiver-output Create a waiver file based on the linter warnings + --waiver-multiline Create multiline --match for waivers + --waiver-output Create a waiver file based on linter warnings -Wall Enable all style warnings -Werror- Convert warnings to errors -Wfuture- Disable unknown message warnings diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index d6b979c81..4108f76e4 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1649,6 +1649,15 @@ Summary: Enable the use of VPI and linking against the :file:`verilated_vpi.cpp` files. +.. option:: --waiver-multiline + + When using :vlopt:`--waiver-output \`, include a match + expression that includes the entire multiline error message as a match + regular expression, as opposed to the default of only matching the first + line of the error message. This provides a starting point for creating + complex waivers, but such generated waivers will likely require editing + for brevity before being reused. + .. option:: --waiver-output Generate a waiver file that contains all waiver statements to suppress diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index e0a15b40d..9a3ce06e8 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1423,8 +1423,13 @@ string AstNode::instanceStr() const { return ""; } void AstNode::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) { + // Don't look for instance name when warning is disabled. + // In case of large number of warnings, this can + // take significant amount of time + const string instanceStrExtra + = m_fileline->warnIsOff(V3Error::s().errorCode()) ? "" : instanceStr(); if (!m_fileline) { - V3Error::v3errorEnd(str, instanceStr()); + V3Error::v3errorEnd(str, instanceStrExtra); } else { std::ostringstream nsstr; nsstr << str.str(); @@ -1434,11 +1439,7 @@ void AstNode::v3errorEnd(std::ostringstream& str) const VL_RELEASE(V3Error::s(). const_cast(this)->dump(nsstr); nsstr << endl; } - // Don't look for instance name when warning is disabled. - // In case of large number of warnings, this can - // take significant amount of time - m_fileline->v3errorEnd( - nsstr, m_fileline->warnIsOff(V3Error::s().errorCode()) ? "" : instanceStr()); + m_fileline->v3errorEnd(nsstr, instanceStrExtra); } } void AstNode::v3errorEndFatal(std::ostringstream& str) const VL_RELEASE(V3Error::s().m_mutex) { diff --git a/src/V3Config.cpp b/src/V3Config.cpp index b90855564..d561570f5 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -300,7 +300,11 @@ public: m_lastIgnore.it = m_ignLines.begin(); } void addIgnoreMatch(V3ErrorCode code, const string& match) { - m_waivers.emplace_back(code, match); + // Since Verilator 5.031 the error message compared has context, so + // allow old rules to still match using a final '*' + string newMatch = match; + if (newMatch.empty() || newMatch.back() != '*') newMatch += '*'; + m_waivers.emplace_back(code, newMatch); } void applyBlock(AstNodeBlock* nodep) { diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 60164e66c..d874ed61d 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -117,6 +117,8 @@ void V3ErrorGuarded::suppressThisWarning() VL_REQUIRES(m_mutex) { // cppcheck-has-bug-suppress constParameter void V3ErrorGuarded::v3errorEnd(std::ostringstream& sstr, const string& extra) VL_REQUIRES(m_mutex) { + // 'extra' is appended to the message, and is is excluded in check for + // duplicate messages. Currently used for reporting instance name. #if defined(__COVERITY__) || defined(__cppcheck__) if (m_errorCode == V3ErrorCode::EC_FATAL) __coverity_panic__(x); #endif diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index 138707039..fd3c04b08 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -413,24 +413,36 @@ bool FileLine::warnIsOff(V3ErrorCode code) const { // cppverilator-suppress constParameter void FileLine::v3errorEnd(std::ostringstream& sstr, const string& extra) VL_RELEASE(V3Error::s().m_mutex) { - std::ostringstream nsstr; + // 'extra' is appended to the message, and is is excluded in check for + // duplicate messages. Currently used for reporting instance name. + std::ostringstream nsstr; // sstr with fileline prefix and context + std::ostringstream wsstr; // sstr for waiver (no fileline) with context if (lastLineno()) nsstr << this; nsstr << sstr.str(); + wsstr << sstr.str(); nsstr << "\n"; - std::ostringstream lstr; + wsstr << "\n"; + std::ostringstream extrass; // extra spaced out for prefix if (!extra.empty()) { - lstr << std::setw(ascii().length()) << " " - << ": " << extra; + extrass << std::setw(ascii().length()) << " " + << ": " << extra; } - m_waive = V3Config::waive(this, V3Error::s().errorCode(), sstr.str()); - if (warnIsOff(V3Error::s().errorCode()) || m_waive) { + if (warnIsOff(V3Error::s().errorCode())) { V3Error::s().suppressThisWarning(); - } else if (!V3Error::s().errorContexted()) { - nsstr << warnContextPrimary(); + } else { + if (!V3Error::s().errorContexted()) { + const string add = warnContextPrimary(); + wsstr << add; + nsstr << add; + } + m_waive = V3Config::waive(this, V3Error::s().errorCode(), wsstr.str()); + if (m_waive) { + V3Error::s().suppressThisWarning(); + } else { + V3Waiver::addEntry(V3Error::s().errorCode(), filename(), wsstr.str()); + } } - if (!warnIsOff(V3Error::s().errorCode()) && !m_waive) - V3Waiver::addEntry(V3Error::s().errorCode(), filename(), sstr.str()); - V3Error::v3errorEnd(nsstr, lstr.str()); + V3Error::v3errorEnd(nsstr, extrass.str()); } string FileLine::warnMore() const VL_REQUIRES(V3Error::s().m_mutex) { diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 6d59c99d1..47f60520b 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1707,6 +1707,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, FileLine::globalWarnOff(V3ErrorCode::WIDTH, false); V3Error::pretendError(V3ErrorCode::WIDTH, false); }); + DECL_OPTION("-waiver-multiline", OnOff, &m_waiverMultiline); DECL_OPTION("-waiver-output", Set, &m_waiverOutput); DECL_OPTION("-x-assign", CbVal, [this, fl](const char* valp) { diff --git a/src/V3Options.h b/src/V3Options.h index 74de94871..3b3b6af5e 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -297,6 +297,7 @@ private: bool m_underlineZero = false; // main switch: --underline-zero; undocumented old Verilator 2 bool m_verilate = true; // main switch: --verilate bool m_vpi = false; // main switch: --vpi + bool m_waiverMultiline = false; // main switch: --waiver-multiline bool m_xInitialEdge = false; // main switch: --x-initial-edge bool m_xmlOnly = false; // main switch: --xml-only bool m_jsonOnly = false; // main switch: --json-only @@ -544,6 +545,7 @@ public: bool reportUnoptflat() const { return m_reportUnoptflat; } bool verilate() const { return m_verilate; } bool vpi() const { return m_vpi; } + bool waiverMultiline() const { return m_waiverMultiline; } bool xInitialEdge() const { return m_xInitialEdge; } bool xmlOnly() const { return m_xmlOnly; } bool jsonOnly() const { return m_jsonOnly; } diff --git a/src/V3Waiver.cpp b/src/V3Waiver.cpp index bd4ad0883..ca8d26a73 100644 --- a/src/V3Waiver.cpp +++ b/src/V3Waiver.cpp @@ -19,21 +19,58 @@ #include "V3Waiver.h" #include "V3File.h" +#include "V3Global.h" #include "V3Options.h" #include #include -void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, const std::string& str) +void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, const std::string& msg) VL_MT_SAFE_EXCLUDES(s_mutex) { if (filename == V3Options::getStdPackagePath()) return; const V3LockGuard lock{s_mutex}; + + string trimmsg = msg; + if (!v3Global.opt.waiverMultiline()) { + const size_t pos = trimmsg.find('\n'); + trimmsg = trimmsg.substr(0, pos); + if (pos != std::string::npos) trimmsg += '*'; + } + { // Remove line numbers and context "\n [0-9] | ", "\n ^[~]+" + string result; + for (const char* cp = trimmsg.c_str(); *cp; cp = *cp ? cp + 1 : cp) { + while (*cp == ' ' || isdigit(*cp)) ++cp; + if (*cp == '|') ++cp; + // ^~~~~ + while (*cp == ' ' || *cp == '^') ++cp; + while (*cp == '~') ++cp; + while (*cp && *cp != '\n') result += *cp++; + while (*cp == '\n') result += *cp++; + } + trimmsg = result; + } + trimmsg += '*'; + { // "\n"->"*", " *"->"*", "* "->"*" + string result; + string add; + result.reserve(trimmsg.size()); + for (const char& c : trimmsg) { + if (c == '*' || !std::isprint(c)) { + add = "*"; + } else if (c == ' ') { + if (add != "*") add += c; + } else { + result += add + c; + add = ""; + } + } + result += add; + trimmsg = result; + } + std::stringstream entry; - const size_t pos = str.find('\n'); entry << "lint_off -rule " << errorCode.ascii() << " -file \"*" << filename << "\" -match \"" - << str.substr(0, pos); - if (pos != std::string::npos) entry << "*"; - entry << "\""; + << trimmsg << "\""; s_waiverList.push_back(entry.str()); } @@ -46,9 +83,9 @@ void V3Waiver::write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex) { *ofp << "`verilator_config\n\n"; - *ofp << "// Below you find suggested waivers. You have three options:\n"; - *ofp << "// 1. Fix the reason for the linter warning\n"; - *ofp << "// 2. Keep the waiver permanently if you are sure this is okay\n"; + *ofp << "// Below are suggested waivers. You have three options:\n"; + *ofp << "// 1. Fix the reason for the linter warning in the Verilog sources\n"; + *ofp << "// 2. Keep the waiver permanently if you are sure it is okay\n"; *ofp << "// 3. Keep the waiver temporarily to suppress the output\n\n"; const V3LockGuard lock{s_mutex}; diff --git a/src/V3Waiver.h b/src/V3Waiver.h index 8ccc1f8e9..af2d415cc 100644 --- a/src/V3Waiver.h +++ b/src/V3Waiver.h @@ -30,7 +30,7 @@ class V3Waiver final { static WaiverList s_waiverList VL_GUARDED_BY(s_mutex); public: - static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& str) + static void addEntry(V3ErrorCode errorCode, const string& filename, const std::string& msg) VL_MT_SAFE_EXCLUDES(s_mutex); static void write(const std::string& filename) VL_MT_SAFE_EXCLUDES(s_mutex); }; diff --git a/test_regress/t/t_waiveroutput.out b/test_regress/t/t_waiveroutput.out index 673c0445a..e111709f1 100644 --- a/test_regress/t/t_waiveroutput.out +++ b/test_regress/t/t_waiveroutput.out @@ -2,9 +2,10 @@ `verilator_config -// Below you find suggested waivers. You have three options: -// 1. Fix the reason for the linter warning -// 2. Keep the waiver permanently if you are sure this is okay +// Below are suggested waivers. You have three options: +// 1. Fix the reason for the linter warning in the Verilog sources +// 2. Keep the waiver permanently if you are sure it is okay // 3. Keep the waiver temporarily to suppress the output -// No waivers needed - great! +// lint_off -rule UNUSEDSIGNAL -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'*" + diff --git a/test_regress/t/t_waiveroutput.py b/test_regress/t/t_waiveroutput.py index 67b6355da..df3799f05 100755 --- a/test_regress/t/t_waiveroutput.py +++ b/test_regress/t/t_waiveroutput.py @@ -15,7 +15,7 @@ test.top_filename = "t/t_waiveroutput.v" out_filename = test.obj_dir + "/" + test.name + ".waiver_gen.out" waiver_filename = "t/" + test.name + ".vlt" -test.compile(v_flags2=[waiver_filename, '--waiver-output', out_filename]) +test.lint(v_flags2=[waiver_filename, '-Wall', '-Wno-fatal', '--waiver-output', out_filename]) test.files_identical(out_filename, test.golden_filename) diff --git a/test_regress/t/t_waiveroutput_allgood.out b/test_regress/t/t_waiveroutput_allgood.out index 673c0445a..6cba8ab6b 100644 --- a/test_regress/t/t_waiveroutput_allgood.out +++ b/test_regress/t/t_waiveroutput_allgood.out @@ -2,9 +2,9 @@ `verilator_config -// Below you find suggested waivers. You have three options: -// 1. Fix the reason for the linter warning -// 2. Keep the waiver permanently if you are sure this is okay +// Below are suggested waivers. You have three options: +// 1. Fix the reason for the linter warning in the Verilog sources +// 2. Keep the waiver permanently if you are sure it is okay // 3. Keep the waiver temporarily to suppress the output // No waivers needed - great! diff --git a/test_regress/t/t_waiveroutput_allgood.py b/test_regress/t/t_waiveroutput_allgood.py index fd20a2c37..502abc15b 100755 --- a/test_regress/t/t_waiveroutput_allgood.py +++ b/test_regress/t/t_waiveroutput_allgood.py @@ -13,9 +13,9 @@ test.scenarios('vlt') test.top_filename = "t/t_waiveroutput.v" out_filename = test.obj_dir + "/" + test.name + ".waiver_gen.vlt" -waiver_filename = "t/" + test.name + ".vlt" -test.compile(v_flags2=[waiver_filename, '--waiver-output', out_filename]) +# Note no Wall +test.lint(v_flags2=['-Wno-WIDTH', '--waiver-output', out_filename]) test.files_identical(out_filename, test.golden_filename) diff --git a/test_regress/t/t_waiveroutput_allgood.vlt b/test_regress/t/t_waiveroutput_allgood.vlt deleted file mode 100644 index 54c5798f2..000000000 --- a/test_regress/t/t_waiveroutput_allgood.vlt +++ /dev/null @@ -1,11 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2020 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -`verilator_config - -lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits." - -lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'" diff --git a/test_regress/t/t_waiveroutput_multiline.out b/test_regress/t/t_waiveroutput_multiline.out new file mode 100644 index 000000000..ecfc68bf5 --- /dev/null +++ b/test_regress/t/t_waiveroutput_multiline.out @@ -0,0 +1,11 @@ +// DESCRIPTION: Verilator output: Waivers generated with --waiver-output + +`verilator_config + +// Below are suggested waivers. You have three options: +// 1. Fix the reason for the linter warning in the Verilog sources +// 2. Keep the waiver permanently if you are sure it is okay +// 3. Keep the waiver temporarily to suppress the output + +// lint_off -rule UNUSEDSIGNAL -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'*reg width_warn = 2'b11;*" + diff --git a/test_regress/t/t_waiveroutput_multiline.py b/test_regress/t/t_waiveroutput_multiline.py index 3f3414f68..ddbe93341 100755 --- a/test_regress/t/t_waiveroutput_multiline.py +++ b/test_regress/t/t_waiveroutput_multiline.py @@ -10,15 +10,15 @@ import vltest_bootstrap test.scenarios('vlt') +test.top_filename = "t/t_waiveroutput.v" -out_filename = test.obj_dir + "/" + test.name + "_waiver_gen.vlt" -waiver_filename = test.obj_dir + "/" + test.name + "_waiver.vlt" +out_filename = test.obj_dir + "/" + test.name + ".waiver_gen.out" +waiver_filename = "t/t_waiveroutput.vlt" -test.compile(v_flags2=['--waiver-output', out_filename], fails=True) +test.lint(v_flags2=[ + waiver_filename, '-Wall', '-Wno-fatal', '--waiver-multiline', '--waiver-output', out_filename +]) -test.file_sed(out_filename, waiver_filename, - lambda line: re.sub(r'\/\/ lint_off', 'lint_off', line)) - -test.compile(v_flags2=[waiver_filename]) +test.files_identical(out_filename, test.golden_filename) test.passes() diff --git a/test_regress/t/t_waiveroutput_wall.py b/test_regress/t/t_waiveroutput_roundtrip.py similarity index 63% rename from test_regress/t/t_waiveroutput_wall.py rename to test_regress/t/t_waiveroutput_roundtrip.py index 9128c7d89..39834358b 100755 --- a/test_regress/t/t_waiveroutput_wall.py +++ b/test_regress/t/t_waiveroutput_roundtrip.py @@ -10,13 +10,15 @@ import vltest_bootstrap test.scenarios('vlt') -test.top_filename = "t/t_waiveroutput.v" out_filename = test.obj_dir + "/" + test.name + ".waiver_gen.out" -waiver_filename = "t/" + test.name + ".vlt" +waiver_filename = test.obj_dir + "/" + test.name + "_waiver.vlt" -test.compile(v_flags2=['-Wall', waiver_filename, '--waiver-output', out_filename]) +test.lint(v_flags2=['-Wall', '-Wno-fatal', '--waiver-output', out_filename]) -test.files_identical(out_filename, test.golden_filename) +test.file_sed(out_filename, waiver_filename, + lambda line: re.sub(r'\/\/ lint_off', 'lint_off', line)) + +test.lint(v_flags2=[waiver_filename]) test.passes() diff --git a/test_regress/t/t_waiveroutput_multiline.v b/test_regress/t/t_waiveroutput_roundtrip.v similarity index 100% rename from test_regress/t/t_waiveroutput_multiline.v rename to test_regress/t/t_waiveroutput_roundtrip.v diff --git a/test_regress/t/t_waiveroutput_wall.out b/test_regress/t/t_waiveroutput_wall.out deleted file mode 100644 index 673c0445a..000000000 --- a/test_regress/t/t_waiveroutput_wall.out +++ /dev/null @@ -1,10 +0,0 @@ -// DESCRIPTION: Verilator output: Waivers generated with --waiver-output - -`verilator_config - -// Below you find suggested waivers. You have three options: -// 1. Fix the reason for the linter warning -// 2. Keep the waiver permanently if you are sure this is okay -// 3. Keep the waiver temporarily to suppress the output - -// No waivers needed - great! diff --git a/test_regress/t/t_waiveroutput_wall.vlt b/test_regress/t/t_waiveroutput_wall.vlt deleted file mode 100644 index 54c5798f2..000000000 --- a/test_regress/t/t_waiveroutput_wall.vlt +++ /dev/null @@ -1,11 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2020 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -`verilator_config - -lint_off -rule WIDTH -file "*t/t_waiveroutput.v" -match "Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits." - -lint_off -rule UNUSED -file "*t/t_waiveroutput.v" -match "Signal is not used: 'width_warn'" From 833c215c4533961d50e5f66b639d95de5da49e53 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 20:49:59 -0500 Subject: [PATCH 061/171] Tests: Move uvm to subdirectory and add context-sensitive waivers --- test_regress/t/t_dist_copyright.py | 4 +-- test_regress/t/t_uvm_all.py | 2 +- test_regress/t/t_uvm_all.v | 2 +- test_regress/t/t_uvm_todo.py | 12 ++----- test_regress/t/t_uvm_todo.v | 2 +- test_regress/t/t_uvm_todo.vlt | 31 +++++++++++++++++++ .../{t_uvm_pkg_all.vh => uvm/uvm_pkg_all.svh} | 0 .../uvm_pkg_todo.svh} | 0 8 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 test_regress/t/t_uvm_todo.vlt rename test_regress/t/{t_uvm_pkg_all.vh => uvm/uvm_pkg_all.svh} (100%) rename test_regress/t/{t_uvm_pkg_todo.vh => uvm/uvm_pkg_todo.svh} (100%) diff --git a/test_regress/t/t_dist_copyright.py b/test_regress/t/t_dist_copyright.py index 33f1ea63f..76ef97b24 100755 --- a/test_regress/t/t_dist_copyright.py +++ b/test_regress/t/t_dist_copyright.py @@ -42,10 +42,10 @@ EXEMPT_FILES_LIST = """ test_regress/t/t_flag_f__3.v test_regress/t/t_fuzz_eof_bad.v test_regress/t/t_incr_void.v - test_regress/t/t_uvm_pkg_all.vh - test_regress/t/t_uvm_pkg_todo.vh test_regress/t/tsub/t_flag_f_tsub.v test_regress/t/tsub/t_flag_f_tsub_inc.v + test_regress/t/uvm/uvm_pkg_all.svh + test_regress/t/uvm/uvm_pkg_todo.svh verilator.pc.in """ diff --git a/test_regress/t/t_uvm_all.py b/test_regress/t/t_uvm_all.py index 790de6b74..f6b5ecee7 100755 --- a/test_regress/t/t_uvm_all.py +++ b/test_regress/t/t_uvm_all.py @@ -13,7 +13,7 @@ test.scenarios('vlt') test.compile( v_flags2=[ - "--binary --timing", # + "--binary --timing +incdir+t/uvm", # "-Wno-PKGNODECL -Wno-IMPLICITSTATIC -Wno-MISINDENT", "-Wno-CASEINCOMPLETE -Wno-CASTCONST -Wno-SYMRSVDWORD -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC", "-Wno-REALCVT", # TODO note mostly related to $realtime - could suppress or fix upstream diff --git a/test_regress/t/t_uvm_all.v b/test_regress/t/t_uvm_all.v index 594c95679..8ecaba7ed 100644 --- a/test_regress/t/t_uvm_all.v +++ b/test_regress/t/t_uvm_all.v @@ -6,7 +6,7 @@ `define UVM_NO_DPI -`include "t_uvm_pkg_all.vh" +`include "uvm_pkg_all.svh" module t(/*AUTOARG*/); diff --git a/test_regress/t/t_uvm_todo.py b/test_regress/t/t_uvm_todo.py index 91773036f..36429f86a 100755 --- a/test_regress/t/t_uvm_todo.py +++ b/test_regress/t/t_uvm_todo.py @@ -12,15 +12,9 @@ import multiprocessing test.scenarios('vlt') -test.compile( - v_flags2=[ - "--timing", # - "-Wno-PKGNODECL -Wno-IMPLICITSTATIC -Wno-MISINDENT", - "-Wno-CASEINCOMPLETE -Wno-CASTCONST -Wno-SYMRSVDWORD -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC", - "-Wno-REALCVT" # TODO note mostly related to $realtime - could suppress or fix upstream - ], - make_flags=['-k -j ' + str(multiprocessing.cpu_count())], - verilator_make_gmake=False) +test.compile(v_flags2=["--timing", "+incdir+t/uvm", "t/t_uvm_todo.vlt"], + make_flags=['-k -j ' + str(multiprocessing.cpu_count())], + verilator_make_gmake=False) #test.execute() diff --git a/test_regress/t/t_uvm_todo.v b/test_regress/t/t_uvm_todo.v index c702f39f3..e77550344 100644 --- a/test_regress/t/t_uvm_todo.v +++ b/test_regress/t/t_uvm_todo.v @@ -6,7 +6,7 @@ `define UVM_NO_DPI -`include "t_uvm_pkg_todo.vh" +`include "uvm_pkg_todo.svh" module t(/*AUTOARG*/); diff --git a/test_regress/t/t_uvm_todo.vlt b/test_regress/t/t_uvm_todo.vlt new file mode 100644 index 000000000..06d6a2395 --- /dev/null +++ b/test_regress/t/t_uvm_todo.vlt @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`verilator_config + +// Whole-file waivers +lint_off -rule WIDTHEXPAND -file "*/uvm_*.svh" +lint_off -rule WIDTHTRUNC -file "*/uvm_*.svh" + +// Context-sensitive waivers +lint_off -rule CASEINCOMPLETE -file "*/uvm_*.svh" -match "* case ({is_R, is_W})*" +lint_off -rule CASEINCOMPLETE -file "*/uvm_*.svh" -match "* case(orig_severity)*" +lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_callback*" +lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_component*" +lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_event*" +lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_report_object*" +lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_sequence_item*" +lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* foreach (abstractions[i])*" +lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* foreach (lock_list[i])*" +lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* rw_access.data=*" +lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* uvm_cmdline_proc =*" +lint_off -rule REALCVT -file "*/uvm_*.svh" -match "* m_time *" +lint_off -rule REALCVT -file "*/uvm_*.svh" -match "*$realtime*" +lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'delete'*" +lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'list'*" +lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'map'*" +lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'override'*" +lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'volatile'*" diff --git a/test_regress/t/t_uvm_pkg_all.vh b/test_regress/t/uvm/uvm_pkg_all.svh similarity index 100% rename from test_regress/t/t_uvm_pkg_all.vh rename to test_regress/t/uvm/uvm_pkg_all.svh diff --git a/test_regress/t/t_uvm_pkg_todo.vh b/test_regress/t/uvm/uvm_pkg_todo.svh similarity index 100% rename from test_regress/t/t_uvm_pkg_todo.vh rename to test_regress/t/uvm/uvm_pkg_todo.svh From 1d063642840c45de2ccb47e56e9e0d2a84f044cc Mon Sep 17 00:00:00 2001 From: Krzysztof Starecki Date: Tue, 12 Nov 2024 17:28:39 +0100 Subject: [PATCH 062/171] Support vpiDefName (#5572) --- docs/CONTRIBUTORS | 1 + include/verilated.cpp | 3 ++- include/verilated.h | 5 ++++- include/verilated_vpi.cpp | 3 +++ src/V3EmitCSyms.cpp | 31 +++++++++++++++++++------------ test_regress/t/t_vpi_escape.cpp | 2 +- test_regress/t/t_vpi_var.cpp | 2 +- 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index dae6f4082..f3913b510 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -126,6 +126,7 @@ Krzysztof Bieganski Krzysztof Boronski Krzysztof Boroński Krzysztof Obłonczek +Krzysztof Starecki Kuba Ober Larry Doolittle Liam Braun diff --git a/include/verilated.cpp b/include/verilated.cpp index 9bb99166c..a4968ccd7 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -3326,7 +3326,7 @@ VerilatedScope::~VerilatedScope() { } void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, - const char* identifier, int8_t timeunit, + const char* identifier, const char* defnamep, int8_t timeunit, const Type& type) VL_MT_UNSAFE { // Slowpath - called once/scope at construction // We don't want the space and reference-count access overhead of strings. @@ -3343,6 +3343,7 @@ void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const m_namep = namep; } m_identifierp = identifier; + m_defnamep = defnamep; Verilated::threadContextp()->impp()->scopeInsert(this); } diff --git a/include/verilated.h b/include/verilated.h index 65ff30c95..aec79542b 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -714,6 +714,7 @@ private: VerilatedVarNameMap* m_varsp = nullptr; // Variable map const char* m_namep = nullptr; // Scope name (Slowpath) const char* m_identifierp = nullptr; // Identifier of scope (with escapes removed) + const char* m_defnamep = nullptr; // Definition name (SCOPE_MODULE only) int8_t m_timeunit = 0; // Timeunit in negative power-of-10 Type m_type = SCOPE_OTHER; // Type of the scope @@ -721,13 +722,15 @@ public: // But internals only - called from VerilatedModule's VerilatedScope() = default; ~VerilatedScope(); void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp, - const char* identifier, int8_t timeunit, const Type& type) VL_MT_UNSAFE; + const char* identifier, const char* defnamep, int8_t timeunit, + const Type& type) VL_MT_UNSAFE; void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE; void varInsert(int finalize, const char* namep, void* datap, bool isParam, VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE; // ACCESSORS const char* name() const VL_MT_SAFE_POSTINIT { return m_namep; } const char* identifier() const VL_MT_SAFE_POSTINIT { return m_identifierp; } + const char* defname() const VL_MT_SAFE_POSTINIT { return m_defnamep; } int8_t timeunit() const VL_MT_SAFE_POSTINIT { return m_timeunit; } VerilatedSyms* symsp() const VL_MT_SAFE_POSTINIT { return m_symsp; } VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT; diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index c066ae8a7..2f8556530 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -268,6 +268,7 @@ protected: bool m_toplevel = false; const char* m_name; const char* m_fullname; + const char* m_defname; public: explicit VerilatedVpioScope(const VerilatedScope* scopep) @@ -275,6 +276,7 @@ public: m_fullname = m_scopep->name(); if (std::strncmp(m_fullname, "TOP.", 4) == 0) m_fullname += 4; m_name = m_scopep->identifier(); + m_defname = m_scopep->defname(); } ~VerilatedVpioScope() override = default; static VerilatedVpioScope* castp(vpiHandle h) { @@ -284,6 +286,7 @@ public: const VerilatedScope* scopep() const { return m_scopep; } const char* name() const override { return m_name; } const char* fullname() const override { return m_fullname; } + const char* defname() const override { return m_defname; } bool toplevel() const { return m_toplevel; } }; diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index e2e020f7f..633d2ba4a 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -43,13 +43,15 @@ class EmitCSyms final : EmitCBaseVisitorConst { const AstNode* m_nodep; const string m_symName; const string m_prettyName; + const string m_defName; const int m_timeunit; string m_type; ScopeData(const AstNode* nodep, const string& symName, const string& prettyName, - int timeunit, const string& type) + const string& defName, int timeunit, const string& type) : m_nodep{nodep} , m_symName{symName} , m_prettyName{prettyName} + , m_defName{defName} , m_timeunit{timeunit} , m_type{type} {} }; @@ -242,8 +244,8 @@ class EmitCSyms final : EmitCBaseVisitorConst { if (v3Global.opt.vpi()) varHierarchyScopes(scpName); if (m_scopeNames.find(scpSym) == m_scopeNames.end()) { // cppcheck-suppress stlFindInsert - m_scopeNames.emplace(scpSym, - ScopeData{varp, scpSym, scpPretty, 0, "SCOPE_OTHER"}); + m_scopeNames.emplace(scpSym, ScopeData{varp, scpSym, scpPretty, "", + 0, "SCOPE_OTHER"}); } m_scopeVars.emplace(scpSym + " " + varp->name(), ScopeVarData{scpSym, varBasePretty, varp, modp, scopep}); @@ -312,7 +314,9 @@ class EmitCSyms final : EmitCBaseVisitorConst { const int timeunit = m_modp->timeunit().powerOfTen(); m_vpiScopeCandidates.emplace( scopeSymString(name), - ScopeData{nodep, scopeSymString(name), name_pretty, timeunit, type}); + ScopeData{nodep, scopeSymString(name), name_pretty, + type == "SCOPE_MODULE" ? nodep->origModName() : "", timeunit, + type}); } } void visit(AstScope* nodep) override { @@ -325,9 +329,9 @@ class EmitCSyms final : EmitCBaseVisitorConst { const string type = VN_IS(nodep->modp(), Package) ? "SCOPE_PACKAGE" : "SCOPE_MODULE"; const string name_pretty = AstNode::vpiName(nodep->shortName()); const int timeunit = m_modp->timeunit().powerOfTen(); - m_vpiScopeCandidates.emplace( - scopeSymString(nodep->name()), - ScopeData{nodep, scopeSymString(nodep->name()), name_pretty, timeunit, type}); + m_vpiScopeCandidates.emplace(scopeSymString(nodep->name()), + ScopeData{nodep, scopeSymString(nodep->name()), + name_pretty, "", timeunit, type}); } iterateChildrenConst(nodep); } @@ -336,8 +340,8 @@ class EmitCSyms final : EmitCBaseVisitorConst { // UINFO(9, "scnameins sp " << nodep->name() << " sp " << nodep->scopePrettySymName() // << " ss" << name << endl); const int timeunit = m_modp ? m_modp->timeunit().powerOfTen() : 0; - m_scopeNames.emplace( - name, ScopeData{nodep, name, nodep->scopePrettySymName(), timeunit, "SCOPE_OTHER"}); + m_scopeNames.emplace(name, ScopeData{nodep, name, nodep->scopePrettySymName(), "", + timeunit, "SCOPE_OTHER"}); if (nodep->dpiExport()) { UASSERT_OBJ(m_cfuncp, nodep, "ScopeName not under DPI function"); m_scopeFuncs.emplace(name + " " + m_cfuncp->name(), @@ -345,9 +349,10 @@ class EmitCSyms final : EmitCBaseVisitorConst { } else { if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) { // cppcheck-suppress stlFindInsert - m_scopeNames.emplace(nodep->scopeDpiName(), ScopeData{nodep, nodep->scopeDpiName(), - nodep->scopePrettyDpiName(), - timeunit, "SCOPE_OTHER"}); + m_scopeNames.emplace(nodep->scopeDpiName(), + ScopeData{nodep, nodep->scopeDpiName(), + nodep->scopePrettyDpiName(), "", timeunit, + "SCOPE_OTHER"}); } } } @@ -885,6 +890,8 @@ void EmitCSyms::emitSymImp() { puts(", "); putsQuoted(protect(scopeDecodeIdentifier(it->second.m_prettyName))); puts(", "); + putsQuoted(it->second.m_defName); + puts(", "); puts(cvtToStr(it->second.m_timeunit)); puts(", VerilatedScope::" + it->second.m_type + ");\n"); ++m_numStmts; diff --git a/test_regress/t/t_vpi_escape.cpp b/test_regress/t/t_vpi_escape.cpp index 7fed0d2e6..73b7875fd 100644 --- a/test_regress/t/t_vpi_escape.cpp +++ b/test_regress/t/t_vpi_escape.cpp @@ -132,7 +132,7 @@ int _mon_check_iter() { TEST_CHECK_CSTR(p, "\\mod.with_dot "); if (TestSimulator::is_verilator()) { p = vpi_get_str(vpiDefName, vh2); - TEST_CHECK_CSTR(p, ""); // Unsupported + TEST_CHECK_CSTR(p, "sub"); } TestVpiHandle vh_null_name = MY_VPI_HANDLE("___0_"); diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 7ed632ecc..82c98783d 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -443,7 +443,7 @@ int _mon_check_varlist() { CHECK_RESULT_CSTR(p, "sub"); if (TestSimulator::is_verilator()) { p = vpi_get_str(vpiDefName, vh2); - CHECK_RESULT_CSTR(p, ""); // Unsupported + CHECK_RESULT_CSTR(p, "sub"); } TestVpiHandle vh10 = vpi_iterate(vpiReg, vh2); From 779cf9248a71e318143fc8a0a29dd51082ebcd5a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 11 Nov 2024 22:22:06 -0500 Subject: [PATCH 063/171] Cleanup/standardize configuration file string handling --- docs/guide/exe_verilator.rst | 17 +++-- src/verilog.y | 138 ++++++++++++++++++++++------------- 2 files changed, 96 insertions(+), 59 deletions(-) diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 4108f76e4..59061613c 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -2088,7 +2088,7 @@ The grammar of configuration commands is as follows: .. option:: lint_off [-rule ] [-file "" [-lines [ - ]]] -.. option:: lint_off [-rule ] [-file ""] [-match ""] +.. option:: lint_off [-rule ] [-file ""] [-match ""] Enable/disables the specified lint warning, in the specified filename (or wildcard with '\*' or '?', or all files if omitted) and range of @@ -2097,17 +2097,18 @@ The grammar of configuration commands is as follows: With lint_off using "\*" will override any lint_on directives in the source, i.e. the warning will still not be printed. - If the -rule is omitted, all lint warnings (see list in + If the :code:`-rule` is omitted, all lint warnings (see list in :vlopt:`-Wno-lint`) are enabled/disabled. This will override all later lint warning enables for the specified region. - If -match is set, the linter warnings are matched against this - (wildcard) string and are waived in case they match, provided with the - rule and file also match. + If :code:`-match` is provided, the linter warnings are matched against + the given wildcard (with '\*' or '?'), and are waived in case they + match, provided the :code:`-rule` and :code:`-file` + also match. The wildcard is compared across the entire multi-line + message; see :vlopt:`--waiver-multiline`. - In previous versions -rule was named -msg. The latter is deprecated, but - still works with a deprecation info; it may be removed in future - versions. + Before version 4.026, :code:`-rule` was named :code:`-msg`, and + :code:`-msg` remained a deprecated alias until Version 5.000. .. option:: public [-module ""] [-task/-function ""] -var "" diff --git a/src/verilog.y b/src/verilog.y index 9854644fd..3819a316a 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7559,77 +7559,77 @@ colon: // Generic colon that isn't making a label (e.g. // VLT Files vltItem: - + // // TODO support arbitrary order of arguments vltOffFront { V3Config::addIgnore($1, false, "*", 0, 0); } - | vltOffFront yVLT_D_FILE yaSTRING - { V3Config::addIgnore($1, false, *$3, 0, 0); } - | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM - { V3Config::addIgnore($1, false, *$3, $5->toUInt(), $5->toUInt() + 1); } - | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM - { V3Config::addIgnore($1, false, *$3, $5->toUInt(), $7->toUInt() + 1); } - | vltOffFront yVLT_D_SCOPE yaSTRING - { if ($1 != V3ErrorCode::I_TRACING) { - $1->v3error("Argument -scope only supported for tracing_on/off"); - } else { - V3Config::addScopeTraceOn(false, *$3, 0); - }} - | vltOffFront yVLT_D_SCOPE yaSTRING yVLT_D_LEVELS yaINTNUM - { if ($1 != V3ErrorCode::I_TRACING) { - $1->v3error("Argument -scope only supported for tracing_on/off_off"); - } else { - V3Config::addScopeTraceOn(false, *$3, $5->toUInt()); - }} - | vltOffFront yVLT_D_FILE yaSTRING yVLT_D_MATCH yaSTRING + | vltOffFront vltDFile + { V3Config::addIgnore($1, false, *$2, 0, 0); } + | vltOffFront vltDFile yVLT_D_LINES yaINTNUM + { V3Config::addIgnore($1, false, *$2, $4->toUInt(), $4->toUInt() + 1); } + | vltOffFront vltDFile yVLT_D_LINES yaINTNUM '-' yaINTNUM + { V3Config::addIgnore($1, false, *$2, $4->toUInt(), $6->toUInt() + 1); } + | vltOffFront vltDFile vltDMatch { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) { $1->v3error("Argument -match only supported for lint_off"); } else { - V3Config::addIgnoreMatch($1, *$3, *$5); + V3Config::addIgnoreMatch($1, *$2, *$3); }} - | vltOnFront - { V3Config::addIgnore($1, true, "*", 0, 0); } - | vltOnFront yVLT_D_FILE yaSTRING - { V3Config::addIgnore($1, true, *$3, 0, 0); } - | vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM - { V3Config::addIgnore($1, true, *$3, $5->toUInt(), $5->toUInt() + 1); } - | vltOnFront yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM '-' yaINTNUM - { V3Config::addIgnore($1, true, *$3, $5->toUInt(), $7->toUInt() + 1); } - | vltOnFront yVLT_D_SCOPE yaSTRING + | vltOffFront vltDScope { if ($1 != V3ErrorCode::I_TRACING) { $1->v3error("Argument -scope only supported for tracing_on/off"); } else { - V3Config::addScopeTraceOn(true, *$3, 0); + V3Config::addScopeTraceOn(false, *$2, 0); }} - | vltOnFront yVLT_D_SCOPE yaSTRING yVLT_D_LEVELS yaINTNUM + | vltOffFront vltDScope vltDLevels { if ($1 != V3ErrorCode::I_TRACING) { $1->v3error("Argument -scope only supported for tracing_on/off_off"); } else { - V3Config::addScopeTraceOn(true, *$3, $5->toUInt()); + V3Config::addScopeTraceOn(false, *$2, $3->toUInt()); + }} + | vltOnFront + { V3Config::addIgnore($1, true, "*", 0, 0); } + | vltOnFront vltDFile + { V3Config::addIgnore($1, true, *$2, 0, 0); } + | vltOnFront vltDFile yVLT_D_LINES yaINTNUM + { V3Config::addIgnore($1, true, *$2, $4->toUInt(), $4->toUInt() + 1); } + | vltOnFront vltDFile yVLT_D_LINES yaINTNUM '-' yaINTNUM + { V3Config::addIgnore($1, true, *$2, $4->toUInt(), $6->toUInt() + 1); } + | vltOnFront vltDScope + { if ($1 != V3ErrorCode::I_TRACING) { + $1->v3error("Argument -scope only supported for tracing_on/off"); + } else { + V3Config::addScopeTraceOn(true, *$2, 0); + }} + | vltOnFront vltDScope vltDLevels + { if ($1 != V3ErrorCode::I_TRACING) { + $1->v3error("Argument -scope only supported for tracing_on/off_off"); + } else { + V3Config::addScopeTraceOn(true, *$2, $3->toUInt()); }} | vltVarAttrFront vltDModuleE vltDFTaskE vltVarAttrVarE attr_event_controlE { V3Config::addVarAttr($1, *$2, *$3, *$4, $1, $5); } | vltInlineFront vltDModuleE vltDFTaskE { V3Config::addInline($1, *$2, *$3, $1); } - | yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING - { V3Config::addCoverageBlockOff(*$3, 0); } - | yVLT_COVERAGE_BLOCK_OFF yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM - { V3Config::addCoverageBlockOff(*$3, $5->toUInt()); } - | yVLT_COVERAGE_BLOCK_OFF yVLT_D_MODULE yaSTRING yVLT_D_BLOCK yaSTRING - { V3Config::addCoverageBlockOff(*$3, *$5); } - | yVLT_FULL_CASE yVLT_D_FILE yaSTRING - { V3Config::addCaseFull(*$3, 0); } - | yVLT_FULL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM - { V3Config::addCaseFull(*$3, $5->toUInt()); } + | yVLT_COVERAGE_BLOCK_OFF vltDFile + { V3Config::addCoverageBlockOff(*$2, 0); } + | yVLT_COVERAGE_BLOCK_OFF vltDFile yVLT_D_LINES yaINTNUM + { V3Config::addCoverageBlockOff(*$2, $4->toUInt()); } + | yVLT_COVERAGE_BLOCK_OFF vltDModule vltDBlock + { V3Config::addCoverageBlockOff(*$2, *$3); } + | yVLT_FULL_CASE vltDFile + { V3Config::addCaseFull(*$2, 0); } + | yVLT_FULL_CASE vltDFile yVLT_D_LINES yaINTNUM + { V3Config::addCaseFull(*$2, $4->toUInt()); } | yVLT_HIER_BLOCK vltDModuleE { V3Config::addModulePragma(*$2, VPragmaType::HIER_BLOCK); } | yVLT_HIER_PARAMS vltDModuleE { V3Config::addModulePragma(*$2, VPragmaType::HIER_PARAMS); } - | yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING - { V3Config::addCaseParallel(*$3, 0); } - | yVLT_PARALLEL_CASE yVLT_D_FILE yaSTRING yVLT_D_LINES yaINTNUM - { V3Config::addCaseParallel(*$3, $5->toUInt()); } - | yVLT_PROFILE_DATA yVLT_D_MODEL yaSTRING yVLT_D_MTASK yaSTRING yVLT_D_COST yaINTNUM - { V3Config::addProfileData($1, *$3, *$5, $7->toUQuad()); } + | yVLT_PARALLEL_CASE vltDFile + { V3Config::addCaseParallel(*$2, 0); } + | yVLT_PARALLEL_CASE vltDFile yVLT_D_LINES yaINTNUM + { V3Config::addCaseParallel(*$2, $4->toUInt()); } + | yVLT_PROFILE_DATA vltDModel vltDMtask vltDCost + { V3Config::addProfileData($1, *$2, *$3, $4->toUQuad()); } ; vltOffFront: @@ -7656,9 +7656,45 @@ vltOnFront: if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown error code: '" << *$3 << "'"); } } ; -vltDModuleE: +vltDBlock: // --block + yVLT_D_BLOCK str { $$ = $2; } + ; + +vltDCost: // --cost + yVLT_D_COST yaINTNUM { $$ = $2; } + ; + +vltDFile: // --file + yVLT_D_FILE str { $$ = $2; } + ; + +vltDLevels: // --levels + yVLT_D_LEVELS yaINTNUM { $$ = $2; } + ; + +vltDMatch: // --match + yVLT_D_MATCH str { $$ = $2; } + ; + +vltDModel: // --model + yVLT_D_MODEL str { $$ = $2; } + ; + +vltDMtask: // --mtask + yVLT_D_MTASK str { $$ = $2; } + ; + +vltDModule: // --module + yVLT_D_MODULE str { $$ = $2; } + ; + +vltDModuleE: // [--module ] /* empty */ { static string unit = "__024unit"; $$ = &unit; } - | yVLT_D_MODULE str { $$ = $2; } + | vltDModule { $$ = $1; } + ; + +vltDScope: // --scope + yVLT_D_SCOPE str { $$ = $2; } ; vltDFTaskE: From a5b2cb6ddf28c716cd241a16f8169ff42abd3119 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 12 Nov 2024 17:19:42 -0500 Subject: [PATCH 064/171] Commentary: Changes update --- Changes | 3 +++ docs/guide/exe_verilator.rst | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Changes b/Changes index ea35c34c9..495f905f5 100644 --- a/Changes +++ b/Changes @@ -15,6 +15,7 @@ Verilator 5.031 devel * Support queue's assignment `push_back/push_front('{})` (#5585) (#5586). [Yilou Wang] * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] +* Support vpiDefName (#3906) (#5572). [Krzysztof Starecki] * Support `pure constraint`. * Add `--no-std-package` as subset-alias of `--no-std`. * Add `--waiver-multiline` for context-sensitive `--waiver-output`. @@ -23,6 +24,7 @@ Verilator 5.031 devel * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add error on `solve before` or soft constraints of `randc` variable. +* Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] @@ -32,6 +34,7 @@ Verilator 5.031 devel * Fix negative assignment pattern keys (#5580). [Iztok Jeras] * Fix duplicate scope identifiers decoding (#5584). [Bartłomiej Chmiel, Antmicro Ltd.] * Fix `rand` dynamic arrays with null handles (#5594). [Ryszard Rozak, Antmicro Ltd.] +* Fix NBAs to unpacked arrays of unpacked structs (#5603). [Geza Lore] Verilator 5.030 2024-10-27 diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 59061613c..5128cd553 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1364,7 +1364,7 @@ Summary: .. option:: --no-std Prevents parsing standard input files, alias for - :opt:`--no-std-package`. This may be extended to prevent reading other + :vlopt:`--no-std-package`. This may be extended to prevent reading other standardized files in future versions. .. option:: --no-std-package @@ -1651,7 +1651,7 @@ Summary: .. option:: --waiver-multiline - When using :vlopt:`--waiver-output \`, include a match + When using :vlopt:`--waiver-output`, include a match expression that includes the entire multiline error message as a match regular expression, as opposed to the default of only matching the first line of the error message. This provides a starting point for creating From 0bf413b26075dd242aed4d70513a34234b15ab3e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 12 Nov 2024 20:21:16 -0500 Subject: [PATCH 065/171] Add `lint_off --contents` in configuration files. (#5606) --- Changes | 1 + docs/guide/exe_verilator.rst | 18 ++++- src/V3Config.cpp | 99 +++++++++++++++++++++++-- src/V3Config.h | 6 +- src/V3FileLine.cpp | 1 + src/V3PreProc.cpp | 15 ++++ src/verilog.l | 1 + src/verilog.y | 19 ++++- test_regress/t/t_uvm_todo.vlt | 50 ++++++++----- test_regress/t/t_vlt_match_contents.out | 7 ++ test_regress/t/t_vlt_match_contents.py | 18 +++++ test_regress/t/t_vlt_match_contents.v | 12 +++ test_regress/t/t_vlt_match_contents.vlt | 12 +++ 13 files changed, 226 insertions(+), 33 deletions(-) create mode 100644 test_regress/t/t_vlt_match_contents.out create mode 100755 test_regress/t/t_vlt_match_contents.py create mode 100644 test_regress/t/t_vlt_match_contents.v create mode 100644 test_regress/t/t_vlt_match_contents.vlt diff --git a/Changes b/Changes index 495f905f5..c609790cc 100644 --- a/Changes +++ b/Changes @@ -19,6 +19,7 @@ Verilator 5.031 devel * Support `pure constraint`. * Add `--no-std-package` as subset-alias of `--no-std`. * Add `--waiver-multiline` for context-sensitive `--waiver-output`. +* Add `lint_off --contents` in configuration files. (#5606) * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 5128cd553..c2bec656b 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1364,7 +1364,7 @@ Summary: .. option:: --no-std Prevents parsing standard input files, alias for - :vlopt:`--no-std-package`. This may be extended to prevent reading other + :opt:`--no-std-package`. This may be extended to prevent reading other standardized files in future versions. .. option:: --no-std-package @@ -1651,7 +1651,7 @@ Summary: .. option:: --waiver-multiline - When using :vlopt:`--waiver-output`, include a match + When using :vlopt:`--waiver-output \`, include a match expression that includes the entire multiline error message as a match regular expression, as opposed to the default of only matching the first line of the error message. This provides a starting point for creating @@ -2088,7 +2088,7 @@ The grammar of configuration commands is as follows: .. option:: lint_off [-rule ] [-file "" [-lines [ - ]]] -.. option:: lint_off [-rule ] [-file ""] [-match ""] +.. option:: lint_off [-rule ] [-file ""] [-contents ""] [-match ""] Enable/disables the specified lint warning, in the specified filename (or wildcard with '\*' or '?', or all files if omitted) and range of @@ -2101,9 +2101,19 @@ The grammar of configuration commands is as follows: :vlopt:`-Wno-lint`) are enabled/disabled. This will override all later lint warning enables for the specified region. + If :code:`-contents` is provided, the input files must contain the given + wildcard (with '\*' or '?'), and are waived in case they match, provided + the :code:`-rule`, :code:`-file`, and :code:`-contents` also match. The + wildcard should be designed to match a single line; it is unspecified if + the wildcard is allowed to match across multiple lines. The input + contents does not include :vlopt:`--std` standard files, nor + configuration files (with :code:`verilator_config`). Typical use for + this is to match a version number present in the Verilog sources, so + that the waiver will only apply to that version of the sources. + If :code:`-match` is provided, the linter warnings are matched against the given wildcard (with '\*' or '?'), and are waived in case they - match, provided the :code:`-rule` and :code:`-file` + match, provided the :code:`-rule`, :code:`-file`, and :code:`-contents` also match. The wildcard is compared across the entire multi-line message; see :vlopt:`--waiver-multiline`. diff --git a/src/V3Config.cpp b/src/V3Config.cpp index d561570f5..b3e82248e 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -118,6 +118,70 @@ public: using V3ConfigVarResolver = V3ConfigWildcardResolver; +//====================================================================== + +class WildcardContents final { + // Not mutex protected, current calling from V3Config::waive is protected by error's mutex + // MEMBERS + std::map m_mapPatterns; // Pattern match results + std::deque m_lines; // Source text lines + + // METHODS + static WildcardContents& s() { // Singleton + static WildcardContents s_s; + return s_s; + } + void clearCacheImp() { m_mapPatterns.clear(); } + void pushTextImp(const string& text) { + // Similar code in VFileContent::pushText() + // Any leftover text is stored on largest line (might be "") + const string leftover = m_lines.back() + text; + m_lines.pop_back(); + + // Insert line-by-line + string::size_type line_start = 0; + while (true) { + const string::size_type line_end = leftover.find('\n', line_start); + if (line_end != string::npos) { + const string oneline(leftover, line_start, line_end - line_start + 1); + if (oneline.size() > 1) m_lines.push_back(oneline); // Keeps newline + UINFO(9, "Push[+" << (m_lines.size() - 1) << "]: " << oneline); + line_start = line_end + 1; + } else { + break; + } + } + // Keep leftover for next time + m_lines.emplace_back(string(leftover, line_start)); // Might be "" + clearCacheImp(); + } + + bool resolveUncachedImp(const string& name) { + for (const string& i : m_lines) { + if (VString::wildmatch(i, name)) return true; + } + return false; + } + bool resolveCachedImp(const string& name) { + // Lookup if it was resolved before, typically is + const auto pair = m_mapPatterns.emplace(name, false); + bool& entryr = pair.first->second; + // Resolve entry when first requested, cache the result + if (pair.second) entryr = resolveUncachedImp(name); + return entryr; + } + +public: + WildcardContents() { + m_lines.emplace_back(""); // start with no leftover + } + ~WildcardContents() = default; + // Return true iff name in parsed contents + static bool resolve(const string& name) { return s().resolveCachedImp(name); } + // Add arbitrary text (need not be line-by-line) + static void pushText(const string& text) { s().pushTextImp(text); } +}; + //###################################################################### // Function or task: Have variables and properties @@ -256,11 +320,28 @@ std::ostream& operator<<(std::ostream& os, const V3ConfigIgnoresLine& rhs) { // and multiple attributes can be attached to a line using V3ConfigLineAttribute = std::bitset; +class WaiverSetting final { +public: + V3ErrorCode m_code; // Error code + string m_contents; // --contents regexp + string m_match; // --match regexp + WaiverSetting(V3ErrorCode code, const string& contents, const string& match) + : m_code{code} + , m_contents{contents} + , m_match{match} {} + ~WaiverSetting() = default; + WaiverSetting& operator=(const WaiverSetting& rhs) { + m_code = rhs.m_code; + m_contents = rhs.m_contents; + m_match = rhs.m_match; + return *this; + } +}; + // File entity class V3ConfigFile final { using LineAttrMap = std::map; // Map line->bitset of attributes using IgnLines = std::multiset; // list of {line,code,on} - using WaiverSetting = std::pair; // Waive code if string matches using Waivers = std::vector; // List of {code,wildcard string} LineAttrMap m_lineAttrs; // Attributes to line mapping @@ -299,12 +380,12 @@ public: m_ignLines.insert(V3ConfigIgnoresLine{code, lineno, on}); m_lastIgnore.it = m_ignLines.begin(); } - void addIgnoreMatch(V3ErrorCode code, const string& match) { + void addIgnoreMatch(V3ErrorCode code, const string& contents, const string& match) { // Since Verilator 5.031 the error message compared has context, so // allow old rules to still match using a final '*' string newMatch = match; if (newMatch.empty() || newMatch.back() != '*') newMatch += '*'; - m_waivers.emplace_back(code, newMatch); + m_waivers.emplace_back(WaiverSetting{code, contents, newMatch}); } void applyBlock(AstNodeBlock* nodep) { @@ -342,8 +423,9 @@ public: bool waive(V3ErrorCode code, const string& match) { if (code.hardError()) return false; for (const auto& itr : m_waivers) { - if ((code.isUnder(itr.first) || (itr.first == V3ErrorCode::I_LINT)) - && VString::wildmatch(match, itr.second)) { + if ((code.isUnder(itr.m_code) || (itr.m_code == V3ErrorCode::I_LINT)) + && VString::wildmatch(match, itr.m_match) + && WildcardContents::resolve(itr.m_contents)) { return true; } } @@ -516,8 +598,9 @@ void V3Config::addIgnore(V3ErrorCode code, bool on, const string& filename, int } } -void V3Config::addIgnoreMatch(V3ErrorCode code, const string& filename, const string& match) { - V3ConfigResolver::s().files().at(filename).addIgnoreMatch(code, match); +void V3Config::addIgnoreMatch(V3ErrorCode code, const string& filename, const string& contents, + const string& match) { + V3ConfigResolver::s().files().at(filename).addIgnoreMatch(code, contents, match); } void V3Config::addInline(FileLine* fl, const string& module, const string& ftask, bool on) { @@ -651,6 +734,8 @@ bool V3Config::getScopeTraceOn(const string& scope) { return V3ConfigResolver::s().scopeTraces().getScopeTraceOn(scope); } +void V3Config::contentsPushText(const string& text) { return WildcardContents::pushText(text); } + bool V3Config::waive(FileLine* filelinep, V3ErrorCode code, const string& message) { V3ConfigFile* filep = V3ConfigResolver::s().files().resolve(filelinep->filename()); if (!filep) return false; diff --git a/src/V3Config.h b/src/V3Config.h index f5e0668b0..c0516cedc 100644 --- a/src/V3Config.h +++ b/src/V3Config.h @@ -34,7 +34,8 @@ public: static void addCoverageBlockOff(const string& file, int lineno); static void addCoverageBlockOff(const string& module, const string& blockname); static void addIgnore(V3ErrorCode code, bool on, const string& filename, int min, int max); - static void addIgnoreMatch(V3ErrorCode code, const string& filename, const string& match); + static void addIgnoreMatch(V3ErrorCode code, const string& filename, const string& contents, + const string& match); static void addInline(FileLine* fl, const string& module, const string& ftask, bool on); static void addModulePragma(const string& module, VPragmaType pragma); static void addProfileData(FileLine* fl, const string& model, const string& key, @@ -53,6 +54,9 @@ public: static uint64_t getProfileData(const string& model, const string& key); static FileLine* getProfileDataFileLine(); static bool getScopeTraceOn(const string& scope); + + static void contentsPushText(const string& text); + static bool waive(FileLine* filelinep, V3ErrorCode code, const string& message); }; diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index fd3c04b08..f7ac9d65c 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -147,6 +147,7 @@ FileLineSingleton::msgEnSetIdx_t FileLineSingleton::msgEnAnd(msgEnSetIdx_t lhsId // VFileContents class functions void VFileContent::pushText(const string& text) { + // Similar code in WildcardContents::pushText() if (m_lines.size() == 0) { m_lines.emplace_back(""); // no such thing as line [0] m_lines.emplace_back(""); // start with no leftover diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 31bd2dccc..6cb95aa28 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -824,6 +824,21 @@ void V3PreProcImp::openFile(FileLine*, VInFilter* filterp, const string& filenam flsp->newContent(); for (const string& i : wholefile) flsp->contentp()->pushText(i); + // Save contents for V3Config --contents + if (filename != V3Options::getStdPackagePath()) { + bool containsVlt = false; + for (const string& i : wholefile) { + // TODO this is overly sensitive, might be in a comment + if (i.find("`verilator_config") != string::npos) { + containsVlt = true; + break; + } + } + if (!containsVlt) { + for (const string& i : wholefile) V3Config::contentsPushText(i); + } + } + // Create new stream structure m_lexp->scanNewFile(flsp); addLineComment(1); // Enter diff --git a/src/verilog.l b/src/verilog.l index 7c11ebc67..1092bedcb 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -137,6 +137,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "tracing_on" { FL; return yVLT_TRACING_ON; } -?"-block" { FL; return yVLT_D_BLOCK; } + -?"-contents" { FL; return yVLT_D_CONTENTS; } -?"-cost" { FL; return yVLT_D_COST; } -?"-file" { FL; return yVLT_D_FILE; } -?"-function" { FL; return yVLT_D_FUNCTION; } diff --git a/src/verilog.y b/src/verilog.y index 3819a316a..47741bcfc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -495,6 +495,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yVLT_TRACING_ON "tracing_on" %token yVLT_D_BLOCK "--block" +%token yVLT_D_CONTENTS "--contents" %token yVLT_D_COST "--cost" %token yVLT_D_FILE "--file" %token yVLT_D_FUNCTION "--function" @@ -7572,7 +7573,19 @@ vltItem: { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) { $1->v3error("Argument -match only supported for lint_off"); } else { - V3Config::addIgnoreMatch($1, *$2, *$3); + V3Config::addIgnoreMatch($1, *$2, "", *$3); + }} + | vltOffFront vltDFile vltDContents + { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) { + $1->v3error("Argument -match only supported for lint_off"); + } else { + V3Config::addIgnoreMatch($1, *$2, *$3, "*"); + }} + | vltOffFront vltDFile vltDContents vltDMatch + { if (($1 == V3ErrorCode::I_COVERAGE) || ($1 == V3ErrorCode::I_TRACING)) { + $1->v3error("Argument -match only supported for lint_off"); + } else { + V3Config::addIgnoreMatch($1, *$2, *$3, *$4); }} | vltOffFront vltDScope { if ($1 != V3ErrorCode::I_TRACING) { @@ -7660,6 +7673,10 @@ vltDBlock: // --block yVLT_D_BLOCK str { $$ = $2; } ; +vltDContents: + yVLT_D_CONTENTS str { $$ = $2; } + ; + vltDCost: // --cost yVLT_D_COST yaINTNUM { $$ = $2; } ; diff --git a/test_regress/t/t_uvm_todo.vlt b/test_regress/t/t_uvm_todo.vlt index 06d6a2395..30d06a2d9 100644 --- a/test_regress/t/t_uvm_todo.vlt +++ b/test_regress/t/t_uvm_todo.vlt @@ -4,28 +4,38 @@ // any use, without warranty, 2024 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +`ifdef _T_UVM_TODO_VLT_ `else +`define _T_UVM_TODO_VLT_ + `verilator_config +// Apply these rules to only UVM base files +`define VLT_UVM_FILES -file "*/uvm_*.svh" -contents "*UVM_VERSION_STRING*" + // Whole-file waivers -lint_off -rule WIDTHEXPAND -file "*/uvm_*.svh" -lint_off -rule WIDTHTRUNC -file "*/uvm_*.svh" +lint_off -rule WIDTHEXPAND `VLT_UVM_FILES +lint_off -rule WIDTHTRUNC `VLT_UVM_FILES // Context-sensitive waivers -lint_off -rule CASEINCOMPLETE -file "*/uvm_*.svh" -match "* case ({is_R, is_W})*" -lint_off -rule CASEINCOMPLETE -file "*/uvm_*.svh" -match "* case(orig_severity)*" -lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_callback*" -lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_component*" -lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_event*" -lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_report_object*" -lint_off -rule CASTCONST -file "*/uvm_*.svh" -match "*class{}uvm_sequence_item*" -lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* foreach (abstractions[i])*" -lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* foreach (lock_list[i])*" -lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* rw_access.data=*" -lint_off -rule MISINDENT -file "*/uvm_*.svh" -match "* uvm_cmdline_proc =*" -lint_off -rule REALCVT -file "*/uvm_*.svh" -match "* m_time *" -lint_off -rule REALCVT -file "*/uvm_*.svh" -match "*$realtime*" -lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'delete'*" -lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'list'*" -lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'map'*" -lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'override'*" -lint_off -rule SYMRSVDWORD -file "*/uvm_*.svh" -match "*'volatile'*" +lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case ({is_R, is_W})*" +lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case(orig_severity)*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_callback*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_component*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_event*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_report_object*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_sequence_item*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (abstractions[i])*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (lock_list[i])*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* rw_access.data=*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* uvm_cmdline_proc =*" +lint_off -rule REALCVT `VLT_UVM_FILES -match "* m_time *" +lint_off -rule REALCVT `VLT_UVM_FILES -match "*$realtime*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'delete'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'list'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'map'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'override'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'volatile'*" + +`undef VLT_UVM_FILES + +`endif // Guard diff --git a/test_regress/t/t_vlt_match_contents.out b/test_regress/t/t_vlt_match_contents.out new file mode 100644 index 000000000..4867ea0bc --- /dev/null +++ b/test_regress/t/t_vlt_match_contents.out @@ -0,0 +1,7 @@ +%Warning-UNUSEDSIGNAL: t/t_vlt_match_contents.v:11:10: Signal is not driven, nor used: 'usignal_contents_mismatch' + : ... note: In instance 't' + 11 | logic usignal_contents_mismatch; + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + ... For warning description see https://verilator.org/warn/UNUSEDSIGNAL?v=latest + ... Use "/* verilator lint_off UNUSEDSIGNAL */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_vlt_match_contents.py b/test_regress/t/t_vlt_match_contents.py new file mode 100755 index 000000000..3c4174c36 --- /dev/null +++ b/test_regress/t/t_vlt_match_contents.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=["--lint-only -Wall t/t_vlt_match_contents.vlt"], + fails=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_vlt_match_contents.v b/test_regress/t/t_vlt_match_contents.v new file mode 100644 index 000000000..dc1c5d6fe --- /dev/null +++ b/test_regress/t/t_vlt_match_contents.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Ethan Sifferman. +// SPDX-License-Identifier: CC0-1.0 + +string MATCH_VERSION = "10.20"; + +module t; + logic usignal_contents_suppress; // Suppressed with -contents + logic usignal_contents_mismatch; // Doesn't match -contents +endmodule diff --git a/test_regress/t/t_vlt_match_contents.vlt b/test_regress/t/t_vlt_match_contents.vlt new file mode 100644 index 000000000..e568f5af0 --- /dev/null +++ b/test_regress/t/t_vlt_match_contents.vlt @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Ethan Sifferman. +// SPDX-License-Identifier: CC0-1.0 + +`verilator_config + +lint_off -rule DECLFILENAME -file "*/t_vlt_match_contents.v" -contents "* MATCH_VERSION*" +lint_off -rule UNUSEDSIGNAL -file "*/t_vlt_match_contents.v" -contents "* MATCH_VERSION*" -match "*MATCH_VERSION*" +lint_off -rule UNUSEDSIGNAL -file "*/t_vlt_match_contents.v" -contents "* MATCH_VERSION*" -match "*usignal_contents_suppress*" +lint_off -rule UNUSEDSIGNAL -file "*/t_vlt_match_contents.v" -contents "* NOT_VERSION*" -match "*usignal_contents_mismatch*" From 09547f839fd49c09075465b4c8f0a2461a613fc8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 12 Nov 2024 21:39:13 -0500 Subject: [PATCH 066/171] Tests: Remove file-number hardcoded dependencies. --- test_regress/t/t_clk_concat.py | 6 +++--- test_regress/t/t_clk_concat_vlt.py | 8 ++++---- test_regress/t/t_dpi_var.py | 8 ++++---- test_regress/t/t_dpi_var_vlt.py | 8 ++++---- test_regress/t/t_func_dotted_inl0.py | 8 ++++---- test_regress/t/t_func_dotted_inl0_vlt.py | 8 ++++---- test_regress/t/t_func_dotted_inl2.py | 4 ++-- test_regress/t/t_func_dotted_inl2_vlt.py | 4 ++-- test_regress/t/t_inst_tree_inl0_pub0.py | 12 ++++++------ test_regress/t/t_inst_tree_inl1_pub0.py | 6 +++--- test_regress/t/t_inst_tree_inl1_pub1.py | 6 +++--- test_regress/t/t_trace_public_sig_vlt.py | 2 +- test_regress/t/t_unopt_combo_isolate.py | 10 +++++----- test_regress/t/t_unopt_combo_isolate_vlt.py | 10 +++++----- 14 files changed, 50 insertions(+), 50 deletions(-) diff --git a/test_regress/t/t_clk_concat.py b/test_regress/t/t_clk_concat.py index 66ab4b571..5aa73e2c5 100755 --- a/test_regress/t/t_clk_concat.py +++ b/test_regress/t/t_clk_concat.py @@ -18,15 +18,15 @@ test.compile(verilator_flags2=["+define+ATTRIBUTES --no-json-edit-nums"]) if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"clk0",.*"loc":"e,74:[^"]*",.*"origName":"clk0",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk0",.*"loc":"\w,74:[^"]*",.*"origName":"clk0",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"clk1",.*"loc":"e,75:[^"]*",.*"origName":"clk1",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk1",.*"loc":"\w,75:[^"]*",.*"origName":"clk1",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"clk2",.*"loc":"e,76:[^"]*",.*"origName":"clk2",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk2",.*"loc":"\w,76:[^"]*",.*"origName":"clk2",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.execute() diff --git a/test_regress/t/t_clk_concat_vlt.py b/test_regress/t/t_clk_concat_vlt.py index b634813cc..e4857e329 100755 --- a/test_regress/t/t_clk_concat_vlt.py +++ b/test_regress/t/t_clk_concat_vlt.py @@ -19,19 +19,19 @@ test.compile(verilator_flags2=["--no-json-edit-nums", "t/t_clk_concat.vlt"]) if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"clk0",.*"loc":"f,78:[^"]*",.*"origName":"clk0",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk0",.*"loc":"\w,78:[^"]*",.*"origName":"clk0",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"clk1",.*"loc":"f,79:[^"]*",.*"origName":"clk1",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk1",.*"loc":"\w,79:[^"]*",.*"origName":"clk1",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"clk2",.*"loc":"f,80:[^"]*",.*"origName":"clk2",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"clk2",.*"loc":"\w,80:[^"]*",.*"origName":"clk2",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"data_in",.*"loc":"f,82:[^"]*",.*"origName":"data_in",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"non_clker",.*"varType":"PORT",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"data_in",.*"loc":"\w,82:[^"]*",.*"origName":"data_in",.*"direction":"INPUT",.*"isSigPublic":true,.*"attrClocker":"non_clker",.*"varType":"PORT",.*"dtypeName":"logic"' ) test.execute() diff --git a/test_regress/t/t_dpi_var.py b/test_regress/t/t_dpi_var.py index 87e0c90a1..0cf3bcd6e 100755 --- a/test_regress/t/t_dpi_var.py +++ b/test_regress/t/t_dpi_var.py @@ -21,19 +21,19 @@ test.compile( if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"formatted",.*"loc":"e,56:[^"]*",.*"origName":"formatted",.*"direction":"INPUT",.*"dtypeName":"string",.*"attrSFormat":true' + r'{"type":"VAR","name":"formatted",.*"loc":"\w,56:[^"]*",.*"origName":"formatted",.*"direction":"INPUT",.*"dtypeName":"string",.*"attrSFormat":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.in",.*"loc":"e,77:[^"]*",.*"origName":"in",.*"dtypeName":"int",.*"isSigUserRdPublic":true' + r'{"type":"VAR","name":"t.sub.in",.*"loc":"\w,77:[^"]*",.*"origName":"in",.*"dtypeName":"int",.*"isSigUserRdPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.fr_a",.*"loc":"e,78:[^"]*",.*"origName":"fr_a",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"t.sub.fr_a",.*"loc":"\w,78:[^"]*",.*"origName":"fr_a",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.fr_b",.*"loc":"e,79:[^"]*",.*"origName":"fr_b",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"t.sub.fr_b",.*"loc":"\w,79:[^"]*",.*"origName":"fr_b",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.execute() diff --git a/test_regress/t/t_dpi_var_vlt.py b/test_regress/t/t_dpi_var_vlt.py index b625c8c09..152593adc 100755 --- a/test_regress/t/t_dpi_var_vlt.py +++ b/test_regress/t/t_dpi_var_vlt.py @@ -24,19 +24,19 @@ test.compile(make_top_shell=False, if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"formatted","addr":"[^"]*","loc":"f,58:[^"]*",.*"origName":"formatted",.*"direction":"INPUT",.*"dtypeName":"string",.*"attrSFormat":true' + r'{"type":"VAR","name":"formatted","addr":"[^"]*","loc":"\w,58:[^"]*",.*"origName":"formatted",.*"direction":"INPUT",.*"dtypeName":"string",.*"attrSFormat":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.in","addr":"[^"]*","loc":"f,81:[^"]*",.*"origName":"in",.*"dtypeName":"int",.*"isSigUserRdPublic":true' + r'{"type":"VAR","name":"t.sub.in","addr":"[^"]*","loc":"\w,81:[^"]*",.*"origName":"in",.*"dtypeName":"int",.*"isSigUserRdPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.fr_a","addr":"[^"]*","loc":"f,82:[^"]*",.*"origName":"fr_a",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"t.sub.fr_a","addr":"[^"]*","loc":"\w,82:[^"]*",.*"origName":"fr_a",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.sub.fr_b","addr":"[^"]*","loc":"f,83:[^"]*",.*"origName":"fr_b",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"t.sub.fr_b","addr":"[^"]*","loc":"\w,83:[^"]*",.*"origName":"fr_b",.*"dtypeName":"int",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.execute() diff --git a/test_regress/t/t_func_dotted_inl0.py b/test_regress/t/t_func_dotted_inl0.py index ac6c72de4..1c461adb2 100755 --- a/test_regress/t/t_func_dotted_inl0.py +++ b/test_regress/t/t_func_dotted_inl0.py @@ -19,17 +19,17 @@ test.compile(v_flags2=['--no-json-edit-nums', '+define+ATTRIBUTES', '+define+NOU if test.vlt_all: test.file_grep( out_filename, - r'{"type":"MODULE","name":"ma",.*"loc":"e,84:[^"]*","origName":"ma",.*,"modPublic":true') + r'{"type":"MODULE","name":"ma",.*"loc":"\w,84:[^"]*","origName":"ma",.*,"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mb",.*"loc":"e,99:[^"]*","origName":"mb",.*"modPublic":true') + r'{"type":"MODULE","name":"mb",.*"loc":"\w,99:[^"]*","origName":"mb",.*"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mc","addr":"[^"]*","loc":"e,127:[^"]*","origName":"mc",.*"modPublic":true' + r'{"type":"MODULE","name":"mc","addr":"[^"]*","loc":"\w,127:[^"]*","origName":"mc",.*"modPublic":true' ) test.file_grep( out_filename, - r'{"type":"MODULE","name":"mc__PB1","addr":"[^"]*","loc":"e,127:[^"]*","origName":"mc",.*"modPublic":true' + r'{"type":"MODULE","name":"mc__PB1","addr":"[^"]*","loc":"\w,127:[^"]*","origName":"mc",.*"modPublic":true' ) test.execute() diff --git a/test_regress/t/t_func_dotted_inl0_vlt.py b/test_regress/t/t_func_dotted_inl0_vlt.py index dd12a7af4..6c739b1b1 100755 --- a/test_regress/t/t_func_dotted_inl0_vlt.py +++ b/test_regress/t/t_func_dotted_inl0_vlt.py @@ -19,16 +19,16 @@ test.compile(v_flags2=["--no-json-edit-nums", test.t_dir + "/t_func_dotted_inl0. if test.vlt_all: test.file_grep( out_filename, - r'{"type":"MODULE","name":"ma",.*"loc":"f,84:[^"]*",.*"origName":"ma",.*"modPublic":true') + r'{"type":"MODULE","name":"ma",.*"loc":"\w,84:[^"]*",.*"origName":"ma",.*"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mb",.*"loc":"f,99:[^"]*",.*"origName":"mb",.*"modPublic":true') + r'{"type":"MODULE","name":"mb",.*"loc":"\w,99:[^"]*",.*"origName":"mb",.*"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mc",.*"loc":"f,127:[^"]*",.*"origName":"mc",.*"modPublic":true') + r'{"type":"MODULE","name":"mc",.*"loc":"\w,127:[^"]*",.*"origName":"mc",.*"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mc__PB1",.*"loc":"f,127:[^"]*",.*"origName":"mc",.*"modPublic":true' + r'{"type":"MODULE","name":"mc__PB1",.*"loc":"\w,127:[^"]*",.*"origName":"mc",.*"modPublic":true' ) test.execute() diff --git a/test_regress/t/t_func_dotted_inl2.py b/test_regress/t/t_func_dotted_inl2.py index 1ab47172d..f0180cc32 100755 --- a/test_regress/t/t_func_dotted_inl2.py +++ b/test_regress/t/t_func_dotted_inl2.py @@ -19,11 +19,11 @@ test.compile(v_flags2=["--no-json-edit-nums", '+define+ATTRIBUTES', '+define+USE if test.vlt_all: modps = test.file_grep( out_filename, - r'{"type":"MODULE","name":"mb","addr":"([^"]*)","loc":"e,99:[^"]*",.*"origName":"mb"') + r'{"type":"MODULE","name":"mb","addr":"([^"]*)","loc":"\w,99:[^"]*",.*"origName":"mb"') modp = modps[0][0] test.file_grep( out_filename, - r'{"type":"CELL","name":"t.ma0.mb0","addr":"[^"]*","loc":"e,87:[^"]*",.*"origName":"mb0",.*"modp":"([^"]*)"', + r'{"type":"CELL","name":"t.ma0.mb0","addr":"[^"]*","loc":"\w,87:[^"]*",.*"origName":"mb0",.*"modp":"([^"]*)"', modp) test.execute() diff --git a/test_regress/t/t_func_dotted_inl2_vlt.py b/test_regress/t/t_func_dotted_inl2_vlt.py index 76860999e..f572fb45b 100755 --- a/test_regress/t/t_func_dotted_inl2_vlt.py +++ b/test_regress/t/t_func_dotted_inl2_vlt.py @@ -18,11 +18,11 @@ test.compile(v_flags2=["--no-json-edit-nums", "t/t_func_dotted_inl2.vlt"]) if test.vlt_all: modps = test.file_grep( out_filename, - r'{"type":"MODULE","name":"mb","addr":"([^"]*)","loc":"f,99:[^"]*",.*"origName":"mb"') + r'{"type":"MODULE","name":"mb","addr":"([^"]*)","loc":"\w,99:[^"]*",.*"origName":"mb"') modp = modps[0][0] test.file_grep( out_filename, - r'{"type":"CELL","name":"t.ma0.mb0","addr":"[^"]*","loc":"f,87:[^"]*",.*"origName":"mb0",.*"modp":"([^"]*)"', + r'{"type":"CELL","name":"t.ma0.mb0","addr":"[^"]*","loc":"\w,87:[^"]*",.*"origName":"mb0",.*"modp":"([^"]*)"', modp) test.execute() diff --git a/test_regress/t/t_inst_tree_inl0_pub0.py b/test_regress/t/t_inst_tree_inl0_pub0.py index 25514c89e..e55e72830 100755 --- a/test_regress/t/t_inst_tree_inl0_pub0.py +++ b/test_regress/t/t_inst_tree_inl0_pub0.py @@ -18,17 +18,17 @@ test.compile(v_flags2=["--no-json-edit-nums", test.t_dir + "/" + test.name + ".v if test.vlt_all: test.file_grep(out_filename, - r'{"type":"MODULE","name":"l1",.*"loc":"f,56:[^"]*",.*"origName":"l1"') + r'{"type":"MODULE","name":"l1",.*"loc":"\w,56:[^"]*",.*"origName":"l1"') test.file_grep(out_filename, - r'{"type":"MODULE","name":"l2",.*"loc":"f,62:[^"]*",.*"origName":"l2"') + r'{"type":"MODULE","name":"l2",.*"loc":"\w,62:[^"]*",.*"origName":"l2"') test.file_grep(out_filename, - r'{"type":"MODULE","name":"l3",.*"loc":"f,69:[^"]*",.*"origName":"l3"') + r'{"type":"MODULE","name":"l3",.*"loc":"\w,69:[^"]*",.*"origName":"l3"') test.file_grep(out_filename, - r'{"type":"MODULE","name":"l4",.*"loc":"f,76:[^"]*",.*"origName":"l4"') + r'{"type":"MODULE","name":"l4",.*"loc":"\w,76:[^"]*",.*"origName":"l4"') test.file_grep(out_filename, - r'{"type":"MODULE","name":"l5__P1",.*"loc":"f,83:[^"]*",.*"origName":"l5"') + r'{"type":"MODULE","name":"l5__P1",.*"loc":"\w,83:[^"]*",.*"origName":"l5"') test.file_grep(out_filename, - r'{"type":"MODULE","name":"l5__P2",.*"loc":"f,83:[^"]*",.*"origName":"l5"') + r'{"type":"MODULE","name":"l5__P2",.*"loc":"\w,83:[^"]*",.*"origName":"l5"') test.execute() test.file_grep(test.run_log_filename, r"\] (%m|.*t\.ps): Clocked") diff --git a/test_regress/t/t_inst_tree_inl1_pub0.py b/test_regress/t/t_inst_tree_inl1_pub0.py index c3ddf6de9..a22a7e648 100755 --- a/test_regress/t/t_inst_tree_inl1_pub0.py +++ b/test_regress/t/t_inst_tree_inl1_pub0.py @@ -21,15 +21,15 @@ test.compile(v_flags2=[ if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"t.u.u0.u0.z1",.*"loc":"f,70:[^"]*",.*"origName":"z1",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"t.u.u0.u0.z1",.*"loc":"\w,70:[^"]*",.*"origName":"z1",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.u.u0.u1.z1",.*"loc":"f,70:[^"]*",.*"origName":"z1",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"t.u.u0.u1.z1",.*"loc":"\w,70:[^"]*",.*"origName":"z1",.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"t.u.u1.u0.z0",.*"loc":"f,70:[^"]*",.*"origName":"z0",.*"dtypeName":"logic"' + r'{"type":"VAR","name":"t.u.u1.u0.z0",.*"loc":"\w,70:[^"]*",.*"origName":"z0",.*"dtypeName":"logic"' ) test.execute() diff --git a/test_regress/t/t_inst_tree_inl1_pub1.py b/test_regress/t/t_inst_tree_inl1_pub1.py index 0a61713b5..2a4f5c98b 100755 --- a/test_regress/t/t_inst_tree_inl1_pub1.py +++ b/test_regress/t/t_inst_tree_inl1_pub1.py @@ -22,15 +22,15 @@ test.compile(v_flags2=[ if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"u.u0.u0.z0",.*"loc":"f,70:[^"]*",.*"origName":"z0",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"u.u0.u0.z0",.*"loc":"\w,70:[^"]*",.*"origName":"z0",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true.*"isSigUserRWPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"u.u0.u0.u0.u0.z1",.*"loc":"f,85:[^"]*",.*"origName":"z1",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"u.u0.u0.u0.u0.z1",.*"loc":"\w,85:[^"]*",.*"origName":"z1",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"u.u0.u1.u0.u0.z",.*"loc":"f,83:[^"]*",.*"origName":"z",.*,"isSigPublic":true,.*dtypeName":"logic",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"u.u0.u1.u0.u0.z",.*"loc":"\w,83:[^"]*",.*"origName":"z",.*,"isSigPublic":true,.*dtypeName":"logic",.*"isSigUserRdPublic":true,.*"isSigUserRWPublic":true' ) test.execute() diff --git a/test_regress/t/t_trace_public_sig_vlt.py b/test_regress/t/t_trace_public_sig_vlt.py index 743751fa9..5cb738257 100755 --- a/test_regress/t/t_trace_public_sig_vlt.py +++ b/test_regress/t/t_trace_public_sig_vlt.py @@ -26,7 +26,7 @@ test.compile(make_top_shell=False, if test.vlt_all: test.file_grep( out_filename, - r'{"type":"VAR","name":"GSR",.*"loc":"f,47:[^"]*",.*"origName":"GSR",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true.*"isSigUserRWPublic":true' + r'{"type":"VAR","name":"GSR",.*"loc":"\w,47:[^"]*",.*"origName":"GSR",.*"isSigPublic":true,.*"dtypeName":"logic",.*"isSigUserRdPublic":true.*"isSigUserRWPublic":true' ) test.execute() diff --git a/test_regress/t/t_unopt_combo_isolate.py b/test_regress/t/t_unopt_combo_isolate.py index c7f9f968d..641974899 100755 --- a/test_regress/t/t_unopt_combo_isolate.py +++ b/test_regress/t/t_unopt_combo_isolate.py @@ -20,23 +20,23 @@ if test.vlt_all: test.file_grep(test.stats, r'Optimizations, isolate_assignments blocks\s+3') test.file_grep( out_filename, - r'{"type":"VAR","name":"t.b",.*"loc":"e,23:[^"]*",.*"origName":"b",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"t.b",.*"loc":"\w,23:[^"]*",.*"origName":"b",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__Vfuncout",.*"loc":"e,99:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__Vfuncout",.*"loc":"\w,99:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__t_crc",.*"loc":"e,100:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__t_crc",.*"loc":"\w,100:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_crc",.*"loc":"e,112:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_crc",.*"loc":"\w,112:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_c",.*"loc":"e,113:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_c",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_c",.*"loc":"\w,113:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_c",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.execute() diff --git a/test_regress/t/t_unopt_combo_isolate_vlt.py b/test_regress/t/t_unopt_combo_isolate_vlt.py index eab58591c..4f3a4988c 100755 --- a/test_regress/t/t_unopt_combo_isolate_vlt.py +++ b/test_regress/t/t_unopt_combo_isolate_vlt.py @@ -21,23 +21,23 @@ if test.vlt_all: test.file_grep(test.stats, r'Optimizations, isolate_assignments blocks\s+3') test.file_grep( out_filename, - r'{"type":"VAR","name":"t.b",.*"loc":"f,23:[^"]*",.*"origName":"b",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"t.b",.*"loc":"\w,23:[^"]*",.*"origName":"b",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__Vfuncout",.*"loc":"f,104:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__Vfuncout",.*"loc":"\w,104:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__Vfuncout",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__t_crc",.*"loc":"f,105:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vfunc_t.file.get_31_16__0__t_crc",.*"loc":"\w,105:[^"]*",.*"origName":"__Vfunc_t__DOT__file__DOT__get_31_16__0__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_crc",.*"loc":"f,115:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_crc",.*"loc":"\w,115:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_crc",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.file_grep( out_filename, - r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_c",.*"loc":"f,116:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_c",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' + r'{"type":"VAR","name":"__Vtask_t.file.set_b_d__1__t_c",.*"loc":"\w,116:[^"]*",.*"origName":"__Vtask_t__DOT__file__DOT__set_b_d__1__t_c",.*"attrIsolateAssign":true,.*"dtypeName":"logic"' ) test.execute() From 3ffea76e1157b467c8b5d1db97264da29f6aacdb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 12 Nov 2024 22:11:19 -0500 Subject: [PATCH 067/171] Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). --- Changes | 7 +- bin/verilator | 1 + docs/guide/exe_verilator.rst | 8 +- include/verilated.v | 4 +- include/verilated_std.sv | 4 +- include/verilated_std_waiver.vlt | 64 +++++ src/V3FileLine.cpp | 10 +- src/V3Global.cpp | 6 + src/V3Options.cpp | 18 +- src/V3Options.h | 3 + src/V3ParseImp.cpp | 4 +- src/V3Waiver.cpp | 1 + test_regress/t/t_dump_json.out | 430 +++++++++++++++--------------- test_regress/t/t_std_waiver.py | 16 ++ test_regress/t/t_std_waiver.v | 13 + test_regress/t/t_std_waiver_no.py | 16 ++ test_regress/t/t_std_waiver_no.v | 13 + test_regress/t/t_uvm_all.py | 3 - test_regress/t/t_uvm_todo.vlt | 34 --- 19 files changed, 386 insertions(+), 269 deletions(-) create mode 100644 include/verilated_std_waiver.vlt create mode 100755 test_regress/t/t_std_waiver.py create mode 100644 test_regress/t/t_std_waiver.v create mode 100755 test_regress/t/t_std_waiver_no.py create mode 100644 test_regress/t/t_std_waiver_no.v diff --git a/Changes b/Changes index c609790cc..f0d5947e2 100644 --- a/Changes +++ b/Changes @@ -17,9 +17,10 @@ Verilator 5.031 devel * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] * Support vpiDefName (#3906) (#5572). [Krzysztof Starecki] * Support `pure constraint`. -* Add `--no-std-package` as subset-alias of `--no-std`. -* Add `--waiver-multiline` for context-sensitive `--waiver-output`. -* Add `lint_off --contents` in configuration files. (#5606) +* Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). +* Add `--no-std-package` as subset-alias of `--no-std` (#5607). +* Add `lint_off --contents` in configuration files (#5606). +* Add `--waiver-multiline` for context-sensitive `--waiver-output` (#5608). * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] diff --git a/bin/verilator b/bin/verilator index 28acbbcf6..4ebb3ddd9 100755 --- a/bin/verilator +++ b/bin/verilator @@ -450,6 +450,7 @@ detailed descriptions of these arguments. --stats-vars Provide statistics on variables --no-std Prevent loading standard files --no-std-package Prevent parsing standard package + --no-std-waiver Prevent parsing standard lint waivers --no-stop-fail Do not call $stop when assertion fails --structs-packed Convert all unpacked structures to packed structures -sv Enable SystemVerilog parsing diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index c2bec656b..ff680e481 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1364,13 +1364,17 @@ Summary: .. option:: --no-std Prevents parsing standard input files, alias for - :opt:`--no-std-package`. This may be extended to prevent reading other - standardized files in future versions. + :opt:`--no-std-package`, :opt:`--no-std-waiver`. This may be extended + to prevent reading other standardized files in future versions. .. option:: --no-std-package Prevents parsing standard `std::` package file. +.. option:: --no-std-waiver + + Prevents parsing standard lint waivers (`verilated_std_waiver.vlt`). + .. option:: --no-stop-fail Don't call $stop when assertion fails. Simulation will continue. diff --git a/include/verilated.v b/include/verilated.v index dcdb10ccd..a230ca814 100644 --- a/include/verilated.v +++ b/include/verilated.v @@ -12,11 +12,11 @@ // // DESCRIPTION: Verilator: Include in verilog files to hide verilator defines -`ifdef _VERILATED_V_ `else +`ifndef _VERILATED_V_ `define _VERILATED_V_ 1 // Hide verilator pragmas from other tools - `ifdef VERILATOR `else + `ifndef VERILATOR `define coverage_block_off `endif diff --git a/include/verilated_std.sv b/include/verilated_std.sv index 2741f03bc..8a1e2541c 100644 --- a/include/verilated_std.sv +++ b/include/verilated_std.sv @@ -14,8 +14,8 @@ /// \file /// \brief Verilated IEEE std:: header /// -/// This file is included automatically by Verilator when a std::mailbox or -/// std::semaphore is referenced. +/// This file is included automatically by Verilator, unless '--no-std-package' +/// is used. /// /// This file is not part of the Verilated public-facing API. /// It is only for internal use. diff --git a/include/verilated_std_waiver.vlt b/include/verilated_std_waiver.vlt new file mode 100644 index 000000000..7a4bd9b6e --- /dev/null +++ b/include/verilated_std_waiver.vlt @@ -0,0 +1,64 @@ +// DESCRIPTION: Verilator: built-in standard lint waivers +// +// Code available from: https://verilator.org +// +//************************************************************************* +// +// Copyright 2022-2024 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 +// +//************************************************************************* +/// +/// \file +/// \brief Verilated built-in standard lint waivers +/// +/// This file is included automatically by Verilator, unless '--no-std-waiver' +/// is used. +/// +/// To assist in building new rules, use: +/// 'verilator --waiver-multiline --waiver-output ' +/// +//************************************************************************* + +`ifndef _VERILATED_STD_WAIVER_VLT_ +`define _VERILATED_STD_WAIVER_VLT_ + +`verilator_config + +//========================================================================= +// UVM + +// Apply these rules to only UVM base files +`define VLT_UVM_FILES -file "*/uvm_*.svh" -contents "*UVM_VERSION_STRING*" + +// Whole-package file waivers +lint_off -rule DECLFILENAME `VLT_UVM_FILES +lint_off -rule VARHIDDEN `VLT_UVM_FILES +lint_off -rule WIDTHEXPAND `VLT_UVM_FILES +lint_off -rule WIDTHTRUNC `VLT_UVM_FILES + +// Context-sensitive waivers +lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case ({is_R, is_W})*" +lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case(orig_severity)*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_callback*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_component*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_event*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_report_object*" +lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_sequence_item*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (abstractions[i])*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (lock_list[i])*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* rw_access.data=*" +lint_off -rule MISINDENT `VLT_UVM_FILES -match "* uvm_cmdline_proc =*" +lint_off -rule REALCVT `VLT_UVM_FILES -match "* m_time *" +lint_off -rule REALCVT `VLT_UVM_FILES -match "*$realtime*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'delete'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'list'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'map'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'override'*" +lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'volatile'*" + +//========================================================================= +`undef VLT_UVM_FILES +`endif // Guard diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index f7ac9d65c..64f62dea0 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -92,9 +92,13 @@ void FileLineSingleton::fileNameNumMapDumpJson(std::ostream& os) { std::string sep = "\n "; os << "\"files\": {"; for (const auto& itr : m_namemap) { - const std::string name - = itr.first == V3Options::getStdPackagePath() ? "" : itr.first; - os << sep << '"' << filenameLetters(itr.second) << '"' << ": {\"filename\":\"" << name + std::string filename = itr.first; + if (filename == V3Options::getStdPackagePath()) { + filename = ""; + } else if (filename == V3Options::getStdWaiverPath()) { + filename = ""; + } + os << sep << '"' << filenameLetters(itr.second) << '"' << ": {\"filename\":\"" << filename << '"' << ", \"realpath\":\"" << V3OutFormatter::quoteNameControls(V3Os::filenameRealPath(itr.first)) << '"' << ", \"language\":\"" << numberToLang(itr.second).ascii() << "\"}"; diff --git a/src/V3Global.cpp b/src/V3Global.cpp index 924a664e1..e65a00081 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -58,6 +58,12 @@ void V3Global::readFiles() { V3Parse parser{v3Global.rootp(), &filter, &parseSyms}; + // Parse the std waivers + if (v3Global.opt.stdWaiver()) { + parser.parseFile( + new FileLine{V3Options::getStdWaiverPath()}, V3Options::getStdWaiverPath(), false, + "Cannot find verilated_std_waiver.vlt containing built-in lint waivers: "); + } // Read .vlt files const V3StringSet& vltFiles = v3Global.opt.vltFiles(); for (const string& filename : vltFiles) { diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 47f60520b..2980e3467 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -568,7 +568,7 @@ string V3Options::filePath(FileLine* fl, const string& modname, const string& la // Return "" if not found. const string filename = V3Os::filenameCleanup(VName::dehash(modname)); if (!V3Os::filenameIsRel(filename)) { - // filename is an absolute path, so can find getStdPackagePath() + // filename is an absolute path, so can find getStdPackagePath()/getStdWaiverPath() string exists = filePathCheckOneDir(filename, ""); if (exists != "") return exists; } @@ -631,7 +631,7 @@ void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) { V3LangCode V3Options::fileLanguage(const string& filename) { string ext = V3Os::filenameNonDir(filename); string::size_type pos; - if (filename == V3Options::getStdPackagePath()) { + if (filename == V3Options::getStdPackagePath() || filename == V3Options::getStdWaiverPath()) { return V3LangCode::mostRecent(); } else if ((pos = ext.rfind('.')) != string::npos) { ext.erase(0, pos + 1); @@ -793,6 +793,9 @@ string V3Options::getenvVERILATOR_SOLVER() { string V3Options::getStdPackagePath() { return V3Os::filenameJoin(getenvVERILATOR_ROOT(), "include", "verilated_std.sv"); } +string V3Options::getStdWaiverPath() { + return V3Os::filenameJoin(getenvVERILATOR_ROOT(), "include", "verilated_std_waiver.vlt"); +} string V3Options::getSupported(const string& var) { // If update below, also update V3Options::showVersion() @@ -1258,7 +1261,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-json-edit-nums", OnOff, &m_jsonEditNums); DECL_OPTION("-json-ids", OnOff, &m_jsonIds); DECL_OPTION("-E", CbOnOff, [this](bool flag) { - if (flag) m_stdPackage = false; + if (flag) { + m_stdPackage = false; + m_stdWaiver = false; + } m_preprocOnly = flag; }); DECL_OPTION("-emit-accessors", OnOff, &m_emitAccessors); @@ -1512,8 +1518,12 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, m_statsVars = flag; m_stats |= flag; }); - DECL_OPTION("-std", CbOnOff, [this](bool flag) { m_stdPackage = flag; }); + DECL_OPTION("-std", CbOnOff, [this](bool flag) { + m_stdPackage = flag; + m_stdWaiver = flag; + }); DECL_OPTION("-std-package", OnOff, &m_stdPackage); + DECL_OPTION("-std-waiver", OnOff, &m_stdWaiver); DECL_OPTION("-stop-fail", OnOff, &m_stopFail); DECL_OPTION("-structs-packed", OnOff, &m_structsPacked); DECL_OPTION("-sv", CbCall, [this]() { m_defaultLanguage = V3LangCode::L1800_2023; }); diff --git a/src/V3Options.h b/src/V3Options.h index 3b3b6af5e..c1b295c90 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -280,6 +280,7 @@ private: bool m_reportUnoptflat = false; // main switch: --report-unoptflat bool m_savable = false; // main switch: --savable bool m_stdPackage = true; // main switch: --std-package + bool m_stdWaiver = true; // main switch: --std-waiver bool m_structsPacked = false; // main switch: --structs-packed bool m_systemC = false; // main switch: --sc: System C instead of simple C++ bool m_stats = false; // main switch: --stats @@ -467,6 +468,7 @@ public: bool stats() const { return m_stats; } bool statsVars() const { return m_statsVars; } bool stdPackage() const { return m_stdPackage; } + bool stdWaiver() const { return m_stdWaiver; } bool structsPacked() const { return m_structsPacked; } bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined bool assertCaseOn() const { return m_assertCase || m_assert; } @@ -741,6 +743,7 @@ public: static string getenvVERILATOR_ROOT(); static string getenvVERILATOR_SOLVER(); static string getStdPackagePath(); + static string getStdWaiverPath(); static string getSupported(const string& var); static bool systemCSystemWide(); static bool systemCFound(); // SystemC installed, or environment points to it diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 39d6ab56c..0458a1735 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -332,7 +332,9 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i } V3Stats::addStatSum(V3Stats::STAT_SOURCE_CHARS, m_ppBytes); - if (debug() && modfilename != V3Options::getStdPackagePath()) dumpInputsFile(); + if (debug() && modfilename != V3Options::getStdPackagePath() + && modfilename != V3Options::getStdWaiverPath()) + dumpInputsFile(); // Parse it if (!v3Global.opt.preprocOnly()) { diff --git a/src/V3Waiver.cpp b/src/V3Waiver.cpp index ca8d26a73..9c10b9c9b 100644 --- a/src/V3Waiver.cpp +++ b/src/V3Waiver.cpp @@ -28,6 +28,7 @@ void V3Waiver::addEntry(V3ErrorCode errorCode, const std::string& filename, const std::string& msg) VL_MT_SAFE_EXCLUDES(s_mutex) { if (filename == V3Options::getStdPackagePath()) return; + if (filename == V3Options::getStdWaiverPath()) return; const V3LockGuard lock{s_mutex}; string trimmsg = msg; diff --git a/test_regress/t/t_dump_json.out b/test_regress/t/t_dump_json.out index 4a302d04d..ac99ae1cd 100644 --- a/test_regress/t/t_dump_json.out +++ b/test_regress/t/t_dump_json.out @@ -1,427 +1,427 @@ {"type":"NETLIST","name":"$root","addr":"(B)","loc":"a,0:0,0:0","timeunit":"1ps","timeprecision":"1ps","typeTablep":"(C)","constPoolp":"(D)","dollarUnitPkgp":"UNLINKED","stdPackagep":"UNLINKED","evalp":"UNLINKED","evalNbap":"UNLINKED","dpiExportTriggerp":"UNLINKED","delaySchedulerp":"UNLINKED","nbaEventp":"UNLINKED","nbaEventTriggerp":"UNLINKED","topScopep":"UNLINKED", "modulesp": [ - {"type":"MODULE","name":"t","addr":"(E)","loc":"d,7:8,7:9","origName":"t","level":2,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], + {"type":"MODULE","name":"t","addr":"(E)","loc":"e,7:8,7:9","origName":"t","level":2,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"PORT","name":"clk","addr":"(F)","loc":"d,9:4,9:7","exprp": []}, - {"type":"VAR","name":"clk","addr":"(G)","loc":"d,11:10,11:13","dtypep":"UNLINKED","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"PORT","name":"clk","addr":"(F)","loc":"e,9:4,9:7","exprp": []}, + {"type":"VAR","name":"clk","addr":"(G)","loc":"e,11:10,11:13","dtypep":"UNLINKED","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"LOGIC_IMPLICIT","addr":"(H)","loc":"d,11:10,11:13","dtypep":"(H)","keyword":"LOGIC_IMPLICIT","generic":false,"rangep": []} + {"type":"BASICDTYPE","name":"LOGIC_IMPLICIT","addr":"(H)","loc":"e,11:10,11:13","dtypep":"(H)","keyword":"LOGIC_IMPLICIT","generic":false,"rangep": []} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"cyc","addr":"(I)","loc":"d,13:12,13:15","dtypep":"UNLINKED","origName":"cyc","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"cyc","addr":"(I)","loc":"e,13:12,13:15","dtypep":"UNLINKED","origName":"cyc","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"integer","addr":"(J)","loc":"d,13:4,13:11","dtypep":"(J)","keyword":"integer","range":"31:0","generic":false,"rangep": []} + {"type":"BASICDTYPE","name":"integer","addr":"(J)","loc":"e,13:4,13:11","dtypep":"(J)","keyword":"integer","range":"31:0","generic":false,"rangep": []} ],"delayp": [], "valuep": [ - {"type":"CONST","name":"?32?sh0","addr":"(K)","loc":"d,13:18,13:19","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(K)","loc":"e,13:18,13:19","dtypep":"(L)"} ],"attrsp": []}, - {"type":"VAR","name":"crc","addr":"(M)","loc":"d,14:15,14:18","dtypep":"UNLINKED","origName":"crc","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"crc","addr":"(M)","loc":"e,14:15,14:18","dtypep":"UNLINKED","origName":"crc","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(N)","loc":"d,14:4,14:7","dtypep":"(N)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(N)","loc":"e,14:4,14:7","dtypep":"(N)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(O)","loc":"d,14:8,14:9","ascending":false, + {"type":"RANGE","name":"","addr":"(O)","loc":"e,14:8,14:9","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh3f","addr":"(P)","loc":"d,14:9,14:11","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3f","addr":"(P)","loc":"e,14:9,14:11","dtypep":"(Q)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(R)","loc":"d,14:12,14:13","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(R)","loc":"e,14:12,14:13","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"sum","addr":"(S)","loc":"d,15:15,15:18","dtypep":"UNLINKED","origName":"sum","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"sum","addr":"(S)","loc":"e,15:15,15:18","dtypep":"UNLINKED","origName":"sum","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"VAR","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(T)","loc":"d,15:4,15:7","dtypep":"(T)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(T)","loc":"e,15:4,15:7","dtypep":"(T)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(U)","loc":"d,15:8,15:9","ascending":false, + {"type":"RANGE","name":"","addr":"(U)","loc":"e,15:8,15:9","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh3f","addr":"(V)","loc":"d,15:9,15:11","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3f","addr":"(V)","loc":"e,15:9,15:11","dtypep":"(Q)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(W)","loc":"d,15:12,15:13","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(W)","loc":"e,15:12,15:13","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"in","addr":"(X)","loc":"d,18:16,18:18","dtypep":"UNLINKED","origName":"in","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"in","addr":"(X)","loc":"e,18:16,18:18","dtypep":"UNLINKED","origName":"in","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(Y)","loc":"d,18:9,18:10","dtypep":"(Y)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(Y)","loc":"e,18:9,18:10","dtypep":"(Y)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(Z)","loc":"d,18:9,18:10","ascending":false, + {"type":"RANGE","name":"","addr":"(Z)","loc":"e,18:9,18:10","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(AB)","loc":"d,18:10,18:12","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(AB)","loc":"e,18:10,18:12","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(CB)","loc":"d,18:13,18:14","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(CB)","loc":"e,18:13,18:14","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"ASSIGNW","name":"","addr":"(DB)","loc":"d,18:19,18:20","dtypep":"UNLINKED", + {"type":"ASSIGNW","name":"","addr":"(DB)","loc":"e,18:19,18:20","dtypep":"UNLINKED", "rhsp": [ - {"type":"SELEXTRACT","name":"","addr":"(EB)","loc":"d,18:24,18:25","dtypep":"UNLINKED", + {"type":"SELEXTRACT","name":"","addr":"(EB)","loc":"e,18:24,18:25","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"crc","addr":"(FB)","loc":"d,18:21,18:24","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(FB)","loc":"e,18:21,18:24","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(GB)","loc":"d,18:25,18:27","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(GB)","loc":"e,18:25,18:27","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(HB)","loc":"d,18:28,18:29","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(HB)","loc":"e,18:28,18:29","dtypep":"(L)"} ],"attrp": []} ], "lhsp": [ - {"type":"PARSEREF","name":"in","addr":"(IB)","loc":"d,18:16,18:18","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"in","addr":"(IB)","loc":"e,18:16,18:18","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": [],"strengthSpecp": []}, - {"type":"VAR","name":"out","addr":"(JB)","loc":"d,22:25,22:28","dtypep":"UNLINKED","origName":"out","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"out","addr":"(JB)","loc":"e,22:25,22:28","dtypep":"UNLINKED","origName":"out","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(KB)","loc":"d,22:9,22:10","dtypep":"(KB)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(KB)","loc":"e,22:9,22:10","dtypep":"(KB)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(LB)","loc":"d,22:9,22:10","ascending":false, + {"type":"RANGE","name":"","addr":"(LB)","loc":"e,22:9,22:10","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(MB)","loc":"d,22:10,22:12","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(MB)","loc":"e,22:10,22:12","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(NB)","loc":"d,22:13,22:14","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(NB)","loc":"e,22:13,22:14","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"CELL","name":"test","addr":"(OB)","loc":"d,25:9,25:13","origName":"test","recursive":false,"modp":"(PB)", + {"type":"CELL","name":"test","addr":"(OB)","loc":"e,25:9,25:13","origName":"test","recursive":false,"modp":"(PB)", "pinsp": [ - {"type":"PIN","name":"out","addr":"(QB)","loc":"d,27:15,27:18","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", + {"type":"PIN","name":"out","addr":"(QB)","loc":"e,27:15,27:18","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", "exprp": [ - {"type":"SELEXTRACT","name":"","addr":"(RB)","loc":"d,27:45,27:46","dtypep":"UNLINKED", + {"type":"SELEXTRACT","name":"","addr":"(RB)","loc":"e,27:45,27:46","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"out","addr":"(SB)","loc":"d,27:42,27:45","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"out","addr":"(SB)","loc":"e,27:42,27:45","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(TB)","loc":"d,27:46,27:48","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(TB)","loc":"e,27:46,27:48","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(UB)","loc":"d,27:49,27:50","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(UB)","loc":"e,27:49,27:50","dtypep":"(L)"} ],"attrp": []} ]}, - {"type":"PIN","name":"clk","addr":"(VB)","loc":"d,29:15,29:18","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", + {"type":"PIN","name":"clk","addr":"(VB)","loc":"e,29:15,29:18","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", "exprp": [ - {"type":"PARSEREF","name":"clk","addr":"(WB)","loc":"d,29:42,29:45","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"clk","addr":"(WB)","loc":"e,29:42,29:45","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ]}, - {"type":"PIN","name":"in","addr":"(XB)","loc":"d,30:15,30:17","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", + {"type":"PIN","name":"in","addr":"(XB)","loc":"e,30:15,30:17","svDotName":true,"svImplicit":false,"modVarp":"UNLINKED","modPTypep":"UNLINKED", "exprp": [ - {"type":"SELEXTRACT","name":"","addr":"(YB)","loc":"d,30:44,30:45","dtypep":"UNLINKED", + {"type":"SELEXTRACT","name":"","addr":"(YB)","loc":"e,30:44,30:45","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"in","addr":"(ZB)","loc":"d,30:42,30:44","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"in","addr":"(ZB)","loc":"e,30:42,30:44","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(AC)","loc":"d,30:45,30:47","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(AC)","loc":"e,30:45,30:47","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(BC)","loc":"d,30:48,30:49","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(BC)","loc":"e,30:48,30:49","dtypep":"(L)"} ],"attrp": []} ]} ],"paramsp": [],"rangep": [],"intfRefsp": []}, - {"type":"VAR","name":"result","addr":"(CC)","loc":"d,33:16,33:22","dtypep":"UNLINKED","origName":"result","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"result","addr":"(CC)","loc":"e,33:16,33:22","dtypep":"UNLINKED","origName":"result","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"WIRE","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(DC)","loc":"d,33:9,33:10","dtypep":"(DC)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(DC)","loc":"e,33:9,33:10","dtypep":"(DC)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(EC)","loc":"d,33:9,33:10","ascending":false, + {"type":"RANGE","name":"","addr":"(EC)","loc":"e,33:9,33:10","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh3f","addr":"(FC)","loc":"d,33:10,33:12","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3f","addr":"(FC)","loc":"e,33:10,33:12","dtypep":"(Q)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(GC)","loc":"d,33:13,33:14","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(GC)","loc":"e,33:13,33:14","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"ASSIGNW","name":"","addr":"(HC)","loc":"d,33:23,33:24","dtypep":"UNLINKED", + {"type":"ASSIGNW","name":"","addr":"(HC)","loc":"e,33:23,33:24","dtypep":"UNLINKED", "rhsp": [ - {"type":"REPLICATE","name":"","addr":"(IC)","loc":"d,33:25,33:26","dtypep":"(JC)", + {"type":"REPLICATE","name":"","addr":"(IC)","loc":"e,33:25,33:26","dtypep":"(JC)", "srcp": [ - {"type":"CONCAT","name":"","addr":"(KC)","loc":"d,33:31,33:32","dtypep":"UNLINKED", + {"type":"CONCAT","name":"","addr":"(KC)","loc":"e,33:31,33:32","dtypep":"UNLINKED", "lhsp": [ - {"type":"CONST","name":"32'h0","addr":"(LC)","loc":"d,33:26,33:31","dtypep":"(MC)"} + {"type":"CONST","name":"32'h0","addr":"(LC)","loc":"e,33:26,33:31","dtypep":"(MC)"} ], "rhsp": [ - {"type":"PARSEREF","name":"out","addr":"(NC)","loc":"d,33:33,33:36","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"out","addr":"(NC)","loc":"e,33:33,33:36","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ]} ], "countp": [ - {"type":"CONST","name":"32'h1","addr":"(OC)","loc":"d,33:25,33:26","dtypep":"(MC)"} + {"type":"CONST","name":"32'h1","addr":"(OC)","loc":"e,33:25,33:26","dtypep":"(MC)"} ]} ], "lhsp": [ - {"type":"PARSEREF","name":"result","addr":"(PC)","loc":"d,33:16,33:22","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"result","addr":"(PC)","loc":"e,33:16,33:22","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": [],"strengthSpecp": []}, - {"type":"ALWAYS","name":"","addr":"(QC)","loc":"d,36:4,36:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [], + {"type":"ALWAYS","name":"","addr":"(QC)","loc":"e,36:4,36:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [], "stmtsp": [ - {"type":"EVENTCONTROL","name":"","addr":"(RC)","loc":"d,36:11,36:12", + {"type":"EVENTCONTROL","name":"","addr":"(RC)","loc":"e,36:11,36:12", "sensesp": [ - {"type":"SENTREE","name":"","addr":"(SC)","loc":"d,36:11,36:12","isMulti":false, + {"type":"SENTREE","name":"","addr":"(SC)","loc":"e,36:11,36:12","isMulti":false, "sensesp": [ - {"type":"SENITEM","name":"","addr":"(TC)","loc":"d,36:14,36:21","edgeType":"POS", + {"type":"SENITEM","name":"","addr":"(TC)","loc":"e,36:14,36:21","edgeType":"POS", "sensp": [ - {"type":"PARSEREF","name":"clk","addr":"(UC)","loc":"d,36:22,36:25","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"clk","addr":"(UC)","loc":"e,36:22,36:25","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"condp": []} ]} ], "stmtsp": [ - {"type":"BEGIN","name":"","addr":"(VC)","loc":"d,36:27,36:32","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], + {"type":"BEGIN","name":"","addr":"(VC)","loc":"e,36:27,36:32","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], "stmtsp": [ - {"type":"ASSIGNDLY","name":"","addr":"(WC)","loc":"d,40:11,40:13","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(WC)","loc":"e,40:11,40:13","dtypep":"UNLINKED", "rhsp": [ - {"type":"ADD","name":"","addr":"(XC)","loc":"d,40:18,40:19","dtypep":"UNLINKED", + {"type":"ADD","name":"","addr":"(XC)","loc":"e,40:18,40:19","dtypep":"UNLINKED", "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(YC)","loc":"d,40:14,40:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(YC)","loc":"e,40:14,40:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"?32?sh1","addr":"(ZC)","loc":"d,40:20,40:21","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh1","addr":"(ZC)","loc":"e,40:20,40:21","dtypep":"(L)"} ]} ], "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(AD)","loc":"d,40:7,40:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(AD)","loc":"e,40:7,40:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []}, - {"type":"ASSIGNDLY","name":"","addr":"(BD)","loc":"d,41:11,41:13","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(BD)","loc":"e,41:11,41:13","dtypep":"UNLINKED", "rhsp": [ - {"type":"REPLICATE","name":"","addr":"(CD)","loc":"d,41:14,41:15","dtypep":"(JC)", + {"type":"REPLICATE","name":"","addr":"(CD)","loc":"e,41:14,41:15","dtypep":"(JC)", "srcp": [ - {"type":"CONCAT","name":"","addr":"(DD)","loc":"d,41:24,41:25","dtypep":"UNLINKED", + {"type":"CONCAT","name":"","addr":"(DD)","loc":"e,41:24,41:25","dtypep":"UNLINKED", "lhsp": [ - {"type":"SELEXTRACT","name":"","addr":"(ED)","loc":"d,41:18,41:19","dtypep":"UNLINKED", + {"type":"SELEXTRACT","name":"","addr":"(ED)","loc":"e,41:18,41:19","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"crc","addr":"(FD)","loc":"d,41:15,41:18","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(FD)","loc":"e,41:15,41:18","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "leftp": [ - {"type":"CONST","name":"?32?sh3e","addr":"(GD)","loc":"d,41:19,41:21","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3e","addr":"(GD)","loc":"e,41:19,41:21","dtypep":"(Q)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(HD)","loc":"d,41:22,41:23","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(HD)","loc":"e,41:22,41:23","dtypep":"(L)"} ],"attrp": []} ], "rhsp": [ - {"type":"XOR","name":"","addr":"(ID)","loc":"d,41:43,41:44","dtypep":"UNLINKED", + {"type":"XOR","name":"","addr":"(ID)","loc":"e,41:43,41:44","dtypep":"UNLINKED", "lhsp": [ - {"type":"XOR","name":"","addr":"(JD)","loc":"d,41:34,41:35","dtypep":"UNLINKED", + {"type":"XOR","name":"","addr":"(JD)","loc":"e,41:34,41:35","dtypep":"UNLINKED", "lhsp": [ - {"type":"SELBIT","name":"","addr":"(KD)","loc":"d,41:29,41:30","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(KD)","loc":"e,41:29,41:30","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"crc","addr":"(LD)","loc":"d,41:26,41:29","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(LD)","loc":"e,41:26,41:29","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh3f","addr":"(MD)","loc":"d,41:30,41:32","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3f","addr":"(MD)","loc":"e,41:30,41:32","dtypep":"(Q)"} ],"thsp": [],"attrp": []} ], "rhsp": [ - {"type":"SELBIT","name":"","addr":"(ND)","loc":"d,41:39,41:40","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(ND)","loc":"e,41:39,41:40","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"crc","addr":"(OD)","loc":"d,41:36,41:39","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(OD)","loc":"e,41:36,41:39","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh2","addr":"(PD)","loc":"d,41:40,41:41","dtypep":"(QD)"} + {"type":"CONST","name":"?32?sh2","addr":"(PD)","loc":"e,41:40,41:41","dtypep":"(QD)"} ],"thsp": [],"attrp": []} ]} ], "rhsp": [ - {"type":"SELBIT","name":"","addr":"(RD)","loc":"d,41:48,41:49","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(RD)","loc":"e,41:48,41:49","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"crc","addr":"(SD)","loc":"d,41:45,41:48","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(SD)","loc":"e,41:45,41:48","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh0","addr":"(TD)","loc":"d,41:49,41:50","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(TD)","loc":"e,41:49,41:50","dtypep":"(L)"} ],"thsp": [],"attrp": []} ]} ]} ], "countp": [ - {"type":"CONST","name":"32'h1","addr":"(UD)","loc":"d,41:14,41:15","dtypep":"(MC)"} + {"type":"CONST","name":"32'h1","addr":"(UD)","loc":"e,41:14,41:15","dtypep":"(MC)"} ]} ], "lhsp": [ - {"type":"PARSEREF","name":"crc","addr":"(VD)","loc":"d,41:7,41:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(VD)","loc":"e,41:7,41:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []}, - {"type":"ASSIGNDLY","name":"","addr":"(WD)","loc":"d,42:11,42:13","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(WD)","loc":"e,42:11,42:13","dtypep":"UNLINKED", "rhsp": [ - {"type":"XOR","name":"","addr":"(XD)","loc":"d,42:21,42:22","dtypep":"UNLINKED", + {"type":"XOR","name":"","addr":"(XD)","loc":"e,42:21,42:22","dtypep":"UNLINKED", "lhsp": [ - {"type":"PARSEREF","name":"result","addr":"(YD)","loc":"d,42:14,42:20","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"result","addr":"(YD)","loc":"e,42:14,42:20","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"REPLICATE","name":"","addr":"(ZD)","loc":"d,42:23,42:24","dtypep":"(JC)", + {"type":"REPLICATE","name":"","addr":"(ZD)","loc":"e,42:23,42:24","dtypep":"(JC)", "srcp": [ - {"type":"CONCAT","name":"","addr":"(AE)","loc":"d,42:33,42:34","dtypep":"UNLINKED", + {"type":"CONCAT","name":"","addr":"(AE)","loc":"e,42:33,42:34","dtypep":"UNLINKED", "lhsp": [ - {"type":"SELEXTRACT","name":"","addr":"(BE)","loc":"d,42:27,42:28","dtypep":"UNLINKED", + {"type":"SELEXTRACT","name":"","addr":"(BE)","loc":"e,42:27,42:28","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"sum","addr":"(CE)","loc":"d,42:24,42:27","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(CE)","loc":"e,42:24,42:27","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "leftp": [ - {"type":"CONST","name":"?32?sh3e","addr":"(DE)","loc":"d,42:28,42:30","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3e","addr":"(DE)","loc":"e,42:28,42:30","dtypep":"(Q)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(EE)","loc":"d,42:31,42:32","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(EE)","loc":"e,42:31,42:32","dtypep":"(L)"} ],"attrp": []} ], "rhsp": [ - {"type":"XOR","name":"","addr":"(FE)","loc":"d,42:52,42:53","dtypep":"UNLINKED", + {"type":"XOR","name":"","addr":"(FE)","loc":"e,42:52,42:53","dtypep":"UNLINKED", "lhsp": [ - {"type":"XOR","name":"","addr":"(GE)","loc":"d,42:43,42:44","dtypep":"UNLINKED", + {"type":"XOR","name":"","addr":"(GE)","loc":"e,42:43,42:44","dtypep":"UNLINKED", "lhsp": [ - {"type":"SELBIT","name":"","addr":"(HE)","loc":"d,42:38,42:39","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(HE)","loc":"e,42:38,42:39","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"sum","addr":"(IE)","loc":"d,42:35,42:38","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(IE)","loc":"e,42:35,42:38","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh3f","addr":"(JE)","loc":"d,42:39,42:41","dtypep":"(Q)"} + {"type":"CONST","name":"?32?sh3f","addr":"(JE)","loc":"e,42:39,42:41","dtypep":"(Q)"} ],"thsp": [],"attrp": []} ], "rhsp": [ - {"type":"SELBIT","name":"","addr":"(KE)","loc":"d,42:48,42:49","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(KE)","loc":"e,42:48,42:49","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"sum","addr":"(LE)","loc":"d,42:45,42:48","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(LE)","loc":"e,42:45,42:48","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh2","addr":"(ME)","loc":"d,42:49,42:50","dtypep":"(QD)"} + {"type":"CONST","name":"?32?sh2","addr":"(ME)","loc":"e,42:49,42:50","dtypep":"(QD)"} ],"thsp": [],"attrp": []} ]} ], "rhsp": [ - {"type":"SELBIT","name":"","addr":"(NE)","loc":"d,42:57,42:58","dtypep":"UNLINKED", + {"type":"SELBIT","name":"","addr":"(NE)","loc":"e,42:57,42:58","dtypep":"UNLINKED", "fromp": [ - {"type":"PARSEREF","name":"sum","addr":"(OE)","loc":"d,42:54,42:57","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(OE)","loc":"e,42:54,42:57","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "bitp": [ - {"type":"CONST","name":"?32?sh0","addr":"(PE)","loc":"d,42:58,42:59","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(PE)","loc":"e,42:58,42:59","dtypep":"(L)"} ],"thsp": [],"attrp": []} ]} ]} ], "countp": [ - {"type":"CONST","name":"32'h1","addr":"(QE)","loc":"d,42:23,42:24","dtypep":"(MC)"} + {"type":"CONST","name":"32'h1","addr":"(QE)","loc":"e,42:23,42:24","dtypep":"(MC)"} ]} ]} ], "lhsp": [ - {"type":"PARSEREF","name":"sum","addr":"(RE)","loc":"d,42:7,42:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(RE)","loc":"e,42:7,42:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []}, - {"type":"IF","name":"","addr":"(SE)","loc":"d,43:7,43:9", + {"type":"IF","name":"","addr":"(SE)","loc":"e,43:7,43:9", "condp": [ - {"type":"EQ","name":"","addr":"(TE)","loc":"d,43:15,43:17","dtypep":"(UE)", + {"type":"EQ","name":"","addr":"(TE)","loc":"e,43:15,43:17","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(VE)","loc":"d,43:11,43:14","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(VE)","loc":"e,43:11,43:14","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"?32?sh0","addr":"(WE)","loc":"d,43:18,43:19","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(WE)","loc":"e,43:18,43:19","dtypep":"(L)"} ]} ], "thensp": [ - {"type":"BEGIN","name":"","addr":"(XE)","loc":"d,43:21,43:26","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], + {"type":"BEGIN","name":"","addr":"(XE)","loc":"e,43:21,43:26","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], "stmtsp": [ - {"type":"ASSIGNDLY","name":"","addr":"(YE)","loc":"d,45:14,45:16","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(YE)","loc":"e,45:14,45:16","dtypep":"UNLINKED", "rhsp": [ - {"type":"CONST","name":"64'h5aef0c8dd70a4497","addr":"(ZE)","loc":"d,45:17,45:38","dtypep":"(AF)"} + {"type":"CONST","name":"64'h5aef0c8dd70a4497","addr":"(ZE)","loc":"e,45:17,45:38","dtypep":"(AF)"} ], "lhsp": [ - {"type":"PARSEREF","name":"crc","addr":"(BF)","loc":"d,45:10,45:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(BF)","loc":"e,45:10,45:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []}, - {"type":"ASSIGNDLY","name":"","addr":"(CF)","loc":"d,46:14,46:16","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(CF)","loc":"e,46:14,46:16","dtypep":"UNLINKED", "rhsp": [ - {"type":"CONST","name":"'0","addr":"(DF)","loc":"d,46:17,46:19","dtypep":"(UE)"} + {"type":"CONST","name":"'0","addr":"(DF)","loc":"e,46:17,46:19","dtypep":"(UE)"} ], "lhsp": [ - {"type":"PARSEREF","name":"sum","addr":"(EF)","loc":"d,46:10,46:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(EF)","loc":"e,46:10,46:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []} ]} ], "elsesp": [ - {"type":"IF","name":"","addr":"(FF)","loc":"d,48:12,48:14", + {"type":"IF","name":"","addr":"(FF)","loc":"e,48:12,48:14", "condp": [ - {"type":"LT","name":"","addr":"(GF)","loc":"d,48:20,48:21","dtypep":"(UE)", + {"type":"LT","name":"","addr":"(GF)","loc":"e,48:20,48:21","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(HF)","loc":"d,48:16,48:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(HF)","loc":"e,48:16,48:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"?32?sha","addr":"(IF)","loc":"d,48:22,48:24","dtypep":"(JF)"} + {"type":"CONST","name":"?32?sha","addr":"(IF)","loc":"e,48:22,48:24","dtypep":"(JF)"} ]} ], "thensp": [ - {"type":"BEGIN","name":"","addr":"(KF)","loc":"d,48:26,48:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], + {"type":"BEGIN","name":"","addr":"(KF)","loc":"e,48:26,48:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], "stmtsp": [ - {"type":"ASSIGNDLY","name":"","addr":"(LF)","loc":"d,49:14,49:16","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(LF)","loc":"e,49:14,49:16","dtypep":"UNLINKED", "rhsp": [ - {"type":"CONST","name":"'0","addr":"(MF)","loc":"d,49:17,49:19","dtypep":"(UE)"} + {"type":"CONST","name":"'0","addr":"(MF)","loc":"e,49:17,49:19","dtypep":"(UE)"} ], "lhsp": [ - {"type":"PARSEREF","name":"sum","addr":"(NF)","loc":"d,49:10,49:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(NF)","loc":"e,49:10,49:13","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []} ]} ], "elsesp": [ - {"type":"IF","name":"","addr":"(OF)","loc":"d,51:12,51:14", + {"type":"IF","name":"","addr":"(OF)","loc":"e,51:12,51:14", "condp": [ - {"type":"LT","name":"","addr":"(PF)","loc":"d,51:20,51:21","dtypep":"(UE)", + {"type":"LT","name":"","addr":"(PF)","loc":"e,51:20,51:21","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(QF)","loc":"d,51:16,51:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(QF)","loc":"e,51:16,51:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"?32?sh5a","addr":"(RF)","loc":"d,51:22,51:24","dtypep":"(SF)"} + {"type":"CONST","name":"?32?sh5a","addr":"(RF)","loc":"e,51:22,51:24","dtypep":"(SF)"} ]} ], "thensp": [ - {"type":"BEGIN","name":"","addr":"(TF)","loc":"d,51:26,51:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [],"stmtsp": []} + {"type":"BEGIN","name":"","addr":"(TF)","loc":"e,51:26,51:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [],"stmtsp": []} ], "elsesp": [ - {"type":"IF","name":"","addr":"(UF)","loc":"d,53:12,53:14", + {"type":"IF","name":"","addr":"(UF)","loc":"e,53:12,53:14", "condp": [ - {"type":"EQ","name":"","addr":"(VF)","loc":"d,53:20,53:22","dtypep":"(UE)", + {"type":"EQ","name":"","addr":"(VF)","loc":"e,53:20,53:22","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"cyc","addr":"(WF)","loc":"d,53:16,53:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"cyc","addr":"(WF)","loc":"e,53:16,53:19","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"?32?sh63","addr":"(XF)","loc":"d,53:23,53:25","dtypep":"(SF)"} + {"type":"CONST","name":"?32?sh63","addr":"(XF)","loc":"e,53:23,53:25","dtypep":"(SF)"} ]} ], "thensp": [ - {"type":"BEGIN","name":"","addr":"(YF)","loc":"d,53:27,53:32","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], + {"type":"BEGIN","name":"","addr":"(YF)","loc":"e,53:27,53:32","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], "stmtsp": [ - {"type":"DISPLAY","name":"","addr":"(ZF)","loc":"d,54:10,54:16", + {"type":"DISPLAY","name":"","addr":"(ZF)","loc":"e,54:10,54:16", "fmtp": [ - {"type":"SFORMATF","name":"","addr":"(AG)","loc":"d,54:10,54:16","dtypep":"(BG)", + {"type":"SFORMATF","name":"","addr":"(AG)","loc":"e,54:10,54:16","dtypep":"(BG)", "exprsp": [ - {"type":"CONST","name":"232'h5b2530745d206379633d3d253064206372633d25782073756d3d25780a","addr":"(CG)","loc":"d,54:17,54:49","dtypep":"(DG)"}, - {"type":"TIME","name":"","addr":"(EG)","loc":"d,54:51,54:56","dtypep":"(FG)","timeunit":"NONE"}, - {"type":"PARSEREF","name":"cyc","addr":"(GG)","loc":"d,54:58,54:61","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []}, - {"type":"PARSEREF","name":"crc","addr":"(HG)","loc":"d,54:63,54:66","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []}, - {"type":"PARSEREF","name":"sum","addr":"(IG)","loc":"d,54:68,54:71","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"CONST","name":"232'h5b2530745d206379633d3d253064206372633d25782073756d3d25780a","addr":"(CG)","loc":"e,54:17,54:49","dtypep":"(DG)"}, + {"type":"TIME","name":"","addr":"(EG)","loc":"e,54:51,54:56","dtypep":"(FG)","timeunit":"NONE"}, + {"type":"PARSEREF","name":"cyc","addr":"(GG)","loc":"e,54:58,54:61","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []}, + {"type":"PARSEREF","name":"crc","addr":"(HG)","loc":"e,54:63,54:66","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []}, + {"type":"PARSEREF","name":"sum","addr":"(IG)","loc":"e,54:68,54:71","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"scopeNamep": []} ],"filep": []}, - {"type":"IF","name":"","addr":"(JG)","loc":"d,55:10,55:12", + {"type":"IF","name":"","addr":"(JG)","loc":"e,55:10,55:12", "condp": [ - {"type":"NEQCASE","name":"","addr":"(KG)","loc":"d,55:18,55:21","dtypep":"(UE)", + {"type":"NEQCASE","name":"","addr":"(KG)","loc":"e,55:18,55:21","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"crc","addr":"(LG)","loc":"d,55:14,55:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"crc","addr":"(LG)","loc":"e,55:14,55:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"64'hc77bb9b3784ea091","addr":"(MG)","loc":"d,55:22,55:42","dtypep":"(AF)"} + {"type":"CONST","name":"64'hc77bb9b3784ea091","addr":"(MG)","loc":"e,55:22,55:42","dtypep":"(AF)"} ]} ], "thensp": [ - {"type":"STOP","name":"","addr":"(NG)","loc":"d,55:44,55:49","isFatal":false} + {"type":"STOP","name":"","addr":"(NG)","loc":"e,55:44,55:49","isFatal":false} ],"elsesp": []}, - {"type":"IF","name":"","addr":"(OG)","loc":"d,58:10,58:12", + {"type":"IF","name":"","addr":"(OG)","loc":"e,58:10,58:12", "condp": [ - {"type":"NEQCASE","name":"","addr":"(PG)","loc":"d,58:18,58:21","dtypep":"(UE)", + {"type":"NEQCASE","name":"","addr":"(PG)","loc":"e,58:18,58:21","dtypep":"(UE)", "lhsp": [ - {"type":"PARSEREF","name":"sum","addr":"(QG)","loc":"d,58:14,58:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"sum","addr":"(QG)","loc":"e,58:14,58:17","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "rhsp": [ - {"type":"CONST","name":"64'h4afe43fb79d7b71e","addr":"(RG)","loc":"d,58:22,58:42","dtypep":"(AF)"} + {"type":"CONST","name":"64'h4afe43fb79d7b71e","addr":"(RG)","loc":"e,58:22,58:42","dtypep":"(AF)"} ]} ], "thensp": [ - {"type":"STOP","name":"","addr":"(SG)","loc":"d,58:44,58:49","isFatal":false} + {"type":"STOP","name":"","addr":"(SG)","loc":"e,58:44,58:49","isFatal":false} ],"elsesp": []}, - {"type":"DISPLAY","name":"","addr":"(TG)","loc":"d,59:10,59:16", + {"type":"DISPLAY","name":"","addr":"(TG)","loc":"e,59:10,59:16", "fmtp": [ - {"type":"SFORMATF","name":"","addr":"(UG)","loc":"d,59:10,59:16","dtypep":"(BG)", + {"type":"SFORMATF","name":"","addr":"(UG)","loc":"e,59:10,59:16","dtypep":"(BG)", "exprsp": [ - {"type":"CONST","name":"168'h2a2d2a20416c6c2046696e6973686564202a2d2a0a","addr":"(VG)","loc":"d,59:17,59:41","dtypep":"(WG)"} + {"type":"CONST","name":"168'h2a2d2a20416c6c2046696e6973686564202a2d2a0a","addr":"(VG)","loc":"e,59:17,59:41","dtypep":"(WG)"} ],"scopeNamep": []} ],"filep": []}, - {"type":"FINISH","name":"","addr":"(XG)","loc":"d,60:10,60:17"} + {"type":"FINISH","name":"","addr":"(XG)","loc":"e,60:10,60:17"} ]} ],"elsesp": []} ]} @@ -431,85 +431,85 @@ ]} ]} ],"activesp": []}, - {"type":"MODULE","name":"Test","addr":"(PB)","loc":"d,66:8,66:12","origName":"Test","level":3,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], + {"type":"MODULE","name":"Test","addr":"(PB)","loc":"e,66:8,66:12","origName":"Test","level":3,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ - {"type":"PORT","name":"out","addr":"(YG)","loc":"d,68:4,68:7","exprp": []}, - {"type":"PORT","name":"clk","addr":"(ZG)","loc":"d,70:4,70:7","exprp": []}, - {"type":"PORT","name":"in","addr":"(AH)","loc":"d,70:9,70:11","exprp": []}, - {"type":"VAR","name":"clk","addr":"(BH)","loc":"d,78:10,78:13","dtypep":"UNLINKED","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"PORT","name":"out","addr":"(YG)","loc":"e,68:4,68:7","exprp": []}, + {"type":"PORT","name":"clk","addr":"(ZG)","loc":"e,70:4,70:7","exprp": []}, + {"type":"PORT","name":"in","addr":"(AH)","loc":"e,70:9,70:11","exprp": []}, + {"type":"VAR","name":"clk","addr":"(BH)","loc":"e,78:10,78:13","dtypep":"UNLINKED","origName":"clk","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"LOGIC_IMPLICIT","addr":"(CH)","loc":"d,78:10,78:13","dtypep":"(CH)","keyword":"LOGIC_IMPLICIT","generic":false,"rangep": []} + {"type":"BASICDTYPE","name":"LOGIC_IMPLICIT","addr":"(CH)","loc":"e,78:10,78:13","dtypep":"(CH)","keyword":"LOGIC_IMPLICIT","generic":false,"rangep": []} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"in","addr":"(DH)","loc":"d,79:17,79:19","dtypep":"UNLINKED","origName":"in","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"in","addr":"(DH)","loc":"e,79:17,79:19","dtypep":"UNLINKED","origName":"in","isSc":false,"isPrimaryIO":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(EH)","loc":"d,79:10,79:11","dtypep":"(EH)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(EH)","loc":"e,79:10,79:11","dtypep":"(EH)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(FH)","loc":"d,79:10,79:11","ascending":false, + {"type":"RANGE","name":"","addr":"(FH)","loc":"e,79:10,79:11","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(GH)","loc":"d,79:11,79:13","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(GH)","loc":"e,79:11,79:13","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(HH)","loc":"d,79:14,79:15","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(HH)","loc":"e,79:14,79:15","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"VAR","name":"out","addr":"(IH)","loc":"d,80:22,80:25","dtypep":"UNLINKED","origName":"out","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", + {"type":"VAR","name":"out","addr":"(IH)","loc":"e,80:22,80:25","dtypep":"UNLINKED","origName":"out","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"PORT","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED", "childDTypep": [ - {"type":"BASICDTYPE","name":"logic","addr":"(JH)","loc":"d,80:11,80:14","dtypep":"(JH)","keyword":"logic","generic":false, + {"type":"BASICDTYPE","name":"logic","addr":"(JH)","loc":"e,80:11,80:14","dtypep":"(JH)","keyword":"logic","generic":false, "rangep": [ - {"type":"RANGE","name":"","addr":"(KH)","loc":"d,80:15,80:16","ascending":false, + {"type":"RANGE","name":"","addr":"(KH)","loc":"e,80:15,80:16","ascending":false, "leftp": [ - {"type":"CONST","name":"?32?sh1f","addr":"(LH)","loc":"d,80:16,80:18","dtypep":"(BB)"} + {"type":"CONST","name":"?32?sh1f","addr":"(LH)","loc":"e,80:16,80:18","dtypep":"(BB)"} ], "rightp": [ - {"type":"CONST","name":"?32?sh0","addr":"(MH)","loc":"d,80:19,80:20","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(MH)","loc":"e,80:19,80:20","dtypep":"(L)"} ]} ]} ],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"ALWAYS","name":"","addr":"(NH)","loc":"d,82:4,82:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [], + {"type":"ALWAYS","name":"","addr":"(NH)","loc":"e,82:4,82:10","keyword":"always","isSuspendable":false,"needProcess":false,"sensesp": [], "stmtsp": [ - {"type":"EVENTCONTROL","name":"","addr":"(OH)","loc":"d,82:11,82:12", + {"type":"EVENTCONTROL","name":"","addr":"(OH)","loc":"e,82:11,82:12", "sensesp": [ - {"type":"SENTREE","name":"","addr":"(PH)","loc":"d,82:11,82:12","isMulti":false, + {"type":"SENTREE","name":"","addr":"(PH)","loc":"e,82:11,82:12","isMulti":false, "sensesp": [ - {"type":"SENITEM","name":"","addr":"(QH)","loc":"d,82:13,82:20","edgeType":"POS", + {"type":"SENITEM","name":"","addr":"(QH)","loc":"e,82:13,82:20","edgeType":"POS", "sensp": [ - {"type":"PARSEREF","name":"clk","addr":"(RH)","loc":"d,82:21,82:24","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"clk","addr":"(RH)","loc":"e,82:21,82:24","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"condp": []} ]} ], "stmtsp": [ - {"type":"BEGIN","name":"","addr":"(SH)","loc":"d,82:26,82:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], + {"type":"BEGIN","name":"","addr":"(SH)","loc":"e,82:26,82:31","generate":false,"genfor":false,"implied":false,"needProcess":false,"unnamed":true,"genforp": [], "stmtsp": [ - {"type":"ASSIGNDLY","name":"","addr":"(TH)","loc":"d,83:11,83:13","dtypep":"UNLINKED", + {"type":"ASSIGNDLY","name":"","addr":"(TH)","loc":"e,83:11,83:13","dtypep":"UNLINKED", "rhsp": [ - {"type":"PARSEREF","name":"in","addr":"(UH)","loc":"d,83:14,83:16","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"in","addr":"(UH)","loc":"e,83:14,83:16","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ], "lhsp": [ - {"type":"PARSEREF","name":"out","addr":"(VH)","loc":"d,83:7,83:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} + {"type":"PARSEREF","name":"out","addr":"(VH)","loc":"e,83:7,83:10","dtypep":"UNLINKED","expect":"TEXT","lhsp": [],"ftaskrefp": []} ],"timingControlp": []}, - {"type":"ASSERTCTL","name":"","addr":"(WH)","loc":"d,86:7,86:17","ctlType":"$assertoff", + {"type":"ASSERTCTL","name":"","addr":"(WH)","loc":"e,86:7,86:17","ctlType":"$assertoff", "controlTypep": [ - {"type":"CONST","name":"32'h4","addr":"(XH)","loc":"d,86:7,86:17","dtypep":"(MC)"} + {"type":"CONST","name":"32'h4","addr":"(XH)","loc":"e,86:7,86:17","dtypep":"(MC)"} ],"assertTypesp": [],"directiveTypesp": []}, - {"type":"ASSERTCTL","name":"","addr":"(YH)","loc":"d,87:7,87:18","ctlType":"$assertkill", + {"type":"ASSERTCTL","name":"","addr":"(YH)","loc":"e,87:7,87:18","ctlType":"$assertkill", "controlTypep": [ - {"type":"CONST","name":"32'h5","addr":"(ZH)","loc":"d,87:7,87:18","dtypep":"(MC)"} + {"type":"CONST","name":"32'h5","addr":"(ZH)","loc":"e,87:7,87:18","dtypep":"(MC)"} ],"assertTypesp": [],"directiveTypesp": []}, - {"type":"ASSERT","name":"","addr":"(AI)","loc":"d,88:7,88:13","type":"[SIMPLE_IMMEDIATE]", + {"type":"ASSERT","name":"","addr":"(AI)","loc":"e,88:7,88:13","type":"[SIMPLE_IMMEDIATE]", "propp": [ - {"type":"CONST","name":"?32?sh0","addr":"(BI)","loc":"d,88:14,88:15","dtypep":"(L)"} + {"type":"CONST","name":"?32?sh0","addr":"(BI)","loc":"e,88:14,88:15","dtypep":"(L)"} ],"sentreep": [],"failsp": [],"passsp": []}, - {"type":"ASSERTCTL","name":"","addr":"(CI)","loc":"d,89:7,89:16","ctlType":"$asserton", + {"type":"ASSERTCTL","name":"","addr":"(CI)","loc":"e,89:7,89:16","ctlType":"$asserton", "controlTypep": [ - {"type":"CONST","name":"32'h3","addr":"(DI)","loc":"d,89:7,89:16","dtypep":"(MC)"} + {"type":"CONST","name":"32'h3","addr":"(DI)","loc":"e,89:7,89:16","dtypep":"(MC)"} ],"assertTypesp": [],"directiveTypesp": []}, - {"type":"ASSERTCTL","name":"","addr":"(EI)","loc":"d,90:7,90:21","ctlType":"", + {"type":"ASSERTCTL","name":"","addr":"(EI)","loc":"e,90:7,90:21","ctlType":"", "controlTypep": [ - {"type":"CONST","name":"?32?sh3","addr":"(FI)","loc":"d,90:22,90:23","dtypep":"(QD)"} + {"type":"CONST","name":"?32?sh3","addr":"(FI)","loc":"e,90:22,90:23","dtypep":"(QD)"} ], "assertTypesp": [ - {"type":"CONST","name":"?32?sh8","addr":"(GI)","loc":"d,90:25,90:26","dtypep":"(JF)"} + {"type":"CONST","name":"?32?sh8","addr":"(GI)","loc":"e,90:25,90:26","dtypep":"(JF)"} ],"directiveTypesp": []} ]} ]} @@ -519,24 +519,24 @@ "miscsp": [ {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(HI)", "typesp": [ - {"type":"BASICDTYPE","name":"integer","addr":"(II)","loc":"c,31:27,31:28","dtypep":"(II)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"c,33:32,33:33","dtypep":"(L)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(UE)","loc":"c,50:22,50:24","dtypep":"(UE)","keyword":"logic","generic":true,"rangep": []}, - {"type":"VOIDDTYPE","name":"","addr":"(HI)","loc":"c,51:21,51:30","dtypep":"(HI)","generic":false}, - {"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"c,125:22,125:23","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(JI)","loc":"c,127:22,127:23","dtypep":"(JI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(KI)","loc":"c,162:17,162:56","dtypep":"(KI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"string","addr":"(BG)","loc":"c,162:10,162:16","dtypep":"(BG)","keyword":"string","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(Q)","loc":"d,14:9,14:11","dtypep":"(Q)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(BB)","loc":"d,18:10,18:12","dtypep":"(BB)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(MC)","loc":"d,33:26,33:31","dtypep":"(MC)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(JC)","loc":"d,33:25,33:26","dtypep":"(JC)","keyword":"logic","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(AF)","loc":"d,45:17,45:38","dtypep":"(AF)","keyword":"logic","range":"63:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(JF)","loc":"d,48:22,48:24","dtypep":"(JF)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(SF)","loc":"d,51:22,51:24","dtypep":"(SF)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(DG)","loc":"d,54:17,54:49","dtypep":"(DG)","keyword":"logic","range":"231:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"QData","addr":"(FG)","loc":"d,54:51,54:56","dtypep":"(FG)","keyword":"QData","range":"63:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(WG)","loc":"d,59:17,59:41","dtypep":"(WG)","keyword":"logic","range":"167:0","generic":true,"rangep": []} + {"type":"BASICDTYPE","name":"integer","addr":"(II)","loc":"d,31:27,31:28","dtypep":"(II)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"d,33:32,33:33","dtypep":"(L)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(UE)","loc":"d,50:22,50:24","dtypep":"(UE)","keyword":"logic","generic":true,"rangep": []}, + {"type":"VOIDDTYPE","name":"","addr":"(HI)","loc":"d,51:21,51:30","dtypep":"(HI)","generic":false}, + {"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"d,125:22,125:23","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(JI)","loc":"d,127:22,127:23","dtypep":"(JI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(KI)","loc":"d,162:17,162:56","dtypep":"(KI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"string","addr":"(BG)","loc":"d,162:10,162:16","dtypep":"(BG)","keyword":"string","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(Q)","loc":"e,14:9,14:11","dtypep":"(Q)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(BB)","loc":"e,18:10,18:12","dtypep":"(BB)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(MC)","loc":"e,33:26,33:31","dtypep":"(MC)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(JC)","loc":"e,33:25,33:26","dtypep":"(JC)","keyword":"logic","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(AF)","loc":"e,45:17,45:38","dtypep":"(AF)","keyword":"logic","range":"63:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(JF)","loc":"e,48:22,48:24","dtypep":"(JF)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(SF)","loc":"e,51:22,51:24","dtypep":"(SF)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(DG)","loc":"e,54:17,54:49","dtypep":"(DG)","keyword":"logic","range":"231:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"QData","addr":"(FG)","loc":"e,54:51,54:56","dtypep":"(FG)","keyword":"QData","range":"63:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(WG)","loc":"e,59:17,59:41","dtypep":"(WG)","keyword":"logic","range":"167:0","generic":true,"rangep": []} ]}, {"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0", "modulep": [ diff --git a/test_regress/t/t_std_waiver.py b/test_regress/t/t_std_waiver.py new file mode 100755 index 000000000..c2d985114 --- /dev/null +++ b/test_regress/t/t_std_waiver.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint() + +test.passes() diff --git a/test_regress/t/t_std_waiver.v b/test_regress/t/t_std_waiver.v new file mode 100644 index 000000000..08cf87957 --- /dev/null +++ b/test_regress/t/t_std_waiver.v @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Rather than look at waivers, just check we included it +`ifndef _VERILATED_STD_WAIVER_VLT_ +`error "Didn't include, no _VERILATED_STD_WAIVER_VLT_" +`endif + +module t; +endmodule diff --git a/test_regress/t/t_std_waiver_no.py b/test_regress/t/t_std_waiver_no.py new file mode 100755 index 000000000..2e67c6a6a --- /dev/null +++ b/test_regress/t/t_std_waiver_no.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(verilator_flags2=['-no-std-waiver']) + +test.passes() diff --git a/test_regress/t/t_std_waiver_no.v b/test_regress/t/t_std_waiver_no.v new file mode 100644 index 000000000..7cf201fb6 --- /dev/null +++ b/test_regress/t/t_std_waiver_no.v @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Rather than look at waivers, just check we included it +`ifdef _VERILATED_STD_WAIVER_VLT_ +`error "Shouldn't have included _VERILATED_STD_WAIVER_VLT_" +`endif + +module t; +endmodule diff --git a/test_regress/t/t_uvm_all.py b/test_regress/t/t_uvm_all.py index f6b5ecee7..ad9ecce9f 100755 --- a/test_regress/t/t_uvm_all.py +++ b/test_regress/t/t_uvm_all.py @@ -14,9 +14,6 @@ test.scenarios('vlt') test.compile( v_flags2=[ "--binary --timing +incdir+t/uvm", # - "-Wno-PKGNODECL -Wno-IMPLICITSTATIC -Wno-MISINDENT", - "-Wno-CASEINCOMPLETE -Wno-CASTCONST -Wno-SYMRSVDWORD -Wno-WIDTHEXPAND -Wno-WIDTHTRUNC", - "-Wno-REALCVT", # TODO note mostly related to $realtime - could suppress or fix upstream "--error-limit 200 --debug-exit-uvm" ], verilator_make_gmake=False) diff --git a/test_regress/t/t_uvm_todo.vlt b/test_regress/t/t_uvm_todo.vlt index 30d06a2d9..d038688e3 100644 --- a/test_regress/t/t_uvm_todo.vlt +++ b/test_regress/t/t_uvm_todo.vlt @@ -4,38 +4,4 @@ // any use, without warranty, 2024 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 -`ifdef _T_UVM_TODO_VLT_ `else -`define _T_UVM_TODO_VLT_ - `verilator_config - -// Apply these rules to only UVM base files -`define VLT_UVM_FILES -file "*/uvm_*.svh" -contents "*UVM_VERSION_STRING*" - -// Whole-file waivers -lint_off -rule WIDTHEXPAND `VLT_UVM_FILES -lint_off -rule WIDTHTRUNC `VLT_UVM_FILES - -// Context-sensitive waivers -lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case ({is_R, is_W})*" -lint_off -rule CASEINCOMPLETE `VLT_UVM_FILES -match "* case(orig_severity)*" -lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_callback*" -lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_component*" -lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_event*" -lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_report_object*" -lint_off -rule CASTCONST `VLT_UVM_FILES -match "*class{}uvm_sequence_item*" -lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (abstractions[i])*" -lint_off -rule MISINDENT `VLT_UVM_FILES -match "* foreach (lock_list[i])*" -lint_off -rule MISINDENT `VLT_UVM_FILES -match "* rw_access.data=*" -lint_off -rule MISINDENT `VLT_UVM_FILES -match "* uvm_cmdline_proc =*" -lint_off -rule REALCVT `VLT_UVM_FILES -match "* m_time *" -lint_off -rule REALCVT `VLT_UVM_FILES -match "*$realtime*" -lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'delete'*" -lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'list'*" -lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'map'*" -lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'override'*" -lint_off -rule SYMRSVDWORD `VLT_UVM_FILES -match "*'volatile'*" - -`undef VLT_UVM_FILES - -`endif // Guard From c7dbdf876af6f897721afc1083338e4cf90a6600 Mon Sep 17 00:00:00 2001 From: github action Date: Wed, 13 Nov 2024 03:12:11 +0000 Subject: [PATCH 068/171] Apply 'make format' --- test_regress/t/t_func_dotted_inl0_vlt.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test_regress/t/t_func_dotted_inl0_vlt.py b/test_regress/t/t_func_dotted_inl0_vlt.py index 6c739b1b1..eefa82526 100755 --- a/test_regress/t/t_func_dotted_inl0_vlt.py +++ b/test_regress/t/t_func_dotted_inl0_vlt.py @@ -25,7 +25,8 @@ if test.vlt_all: r'{"type":"MODULE","name":"mb",.*"loc":"\w,99:[^"]*",.*"origName":"mb",.*"modPublic":true') test.file_grep( out_filename, - r'{"type":"MODULE","name":"mc",.*"loc":"\w,127:[^"]*",.*"origName":"mc",.*"modPublic":true') + r'{"type":"MODULE","name":"mc",.*"loc":"\w,127:[^"]*",.*"origName":"mc",.*"modPublic":true' + ) test.file_grep( out_filename, r'{"type":"MODULE","name":"mc__PB1",.*"loc":"\w,127:[^"]*",.*"origName":"mc",.*"modPublic":true' From e223228ec0eb34fecdafa6b9a3061fe3f3c39716 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 12 Nov 2024 22:40:54 -0500 Subject: [PATCH 069/171] Fix installation of waiver file (#5607) --- CMakeLists.txt | 1 + Makefile.in | 1 + 2 files changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d1528033..17a2fefab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,6 +173,7 @@ install( PATTERN "include/verilated_config.h" PATTERN "include/*.[chv]" PATTERN "include/*.cpp" + PATTERN "include/*.vlt" PATTERN "include/*.sv" PATTERN "include/gtkwave/*.[chv]*" PATTERN "include/vltstd/*.[chv]*" diff --git a/Makefile.in b/Makefile.in index 025294225..a9484494d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -249,6 +249,7 @@ VL_INST_INC_BLDDIR_FILES = \ # Files under srcdir, instead of build time VL_INST_INC_SRCDIR_FILES = \ include/*.[chv]* \ + include/*.vlt \ include/*.sv \ include/gtkwave/*.[chv]* \ include/vltstd/*.[chv]* \ From 192236a832818a8e25b881ba599aa45569d46a43 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Nov 2024 07:09:29 -0500 Subject: [PATCH 070/171] Fix `module automatic` --- src/V3LinkParse.cpp | 21 ++++++++++++-- test_regress/t/t_mod_automatic.py | 18 ++++++++++++ test_regress/t/t_mod_automatic.v | 47 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_mod_automatic.py create mode 100644 test_regress/t/t_mod_automatic.v diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 766eaabbd..1a8956a43 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -62,6 +62,7 @@ class LinkParseVisitor final : public VNVisitor { int m_beginDepth = 0; // How many begin blocks above current node within current AstNodeModule VLifetime m_lifetime = VLifetime::STATIC; // Propagating lifetime bool m_insideLoop = false; // True if the node is inside a loop + bool m_lifetimeAllowed = false; // True to allow lifetime settings VDouble0 m_statModules; // Number of modules seen // METHODS @@ -185,6 +186,8 @@ class LinkParseVisitor final : public VNVisitor { VL_RESTORER(m_ftaskp); VL_RESTORER(m_lifetime); m_ftaskp = nodep; + VL_RESTORER(m_lifetimeAllowed); + m_lifetimeAllowed = true; if (!nodep->lifetime().isNone()) { m_lifetime = nodep->lifetime(); } else { @@ -290,7 +293,13 @@ class LinkParseVisitor final : public VNVisitor { "loop converted to automatic"); } if (nodep->varType() != VVarType::PORT) { - if (nodep->lifetime().isNone()) nodep->lifetime(m_lifetime); + if (nodep->lifetime().isNone()) { + if (m_lifetimeAllowed) { + nodep->lifetime(m_lifetime); + } else { // Module's always static per IEEE 1800-2023 6.21 + nodep->lifetime(VLifetime::STATIC); + } + } } else if (m_ftaskp) { nodep->lifetime(VLifetime::AUTOMATIC); } else if (nodep->lifetime() @@ -612,6 +621,7 @@ class LinkParseVisitor final : public VNVisitor { VL_RESTORER(m_genblkNum); VL_RESTORER(m_beginDepth); VL_RESTORER(m_lifetime); + VL_RESTORER(m_lifetimeAllowed); { // Module: Create sim table for entire module and iterate cleanFileline(nodep); @@ -624,6 +634,7 @@ class LinkParseVisitor final : public VNVisitor { m_beginDepth = 0; m_valueModp = nodep; m_lifetime = nodep->lifetime(); + m_lifetimeAllowed = VN_IS(nodep, Class); if (m_lifetime.isNone()) { m_lifetime = VN_IS(nodep, Class) ? VLifetime::AUTOMATIC : VLifetime::STATIC; } @@ -643,10 +654,16 @@ class LinkParseVisitor final : public VNVisitor { m_valueModp = nullptr; iterateChildren(nodep); } - void visit(AstNodeProcedure* nodep) override { visitIterateNoValueMod(nodep); } + void visit(AstNodeProcedure* nodep) override { + VL_RESTORER(m_lifetimeAllowed); + m_lifetimeAllowed = true; + visitIterateNoValueMod(nodep); + } void visit(AstAlways* nodep) override { VL_RESTORER(m_inAlways); m_inAlways = true; + VL_RESTORER(m_lifetimeAllowed); + m_lifetimeAllowed = true; visitIterateNoValueMod(nodep); } void visit(AstCover* nodep) override { visitIterateNoValueMod(nodep); } diff --git a/test_regress/t/t_mod_automatic.py b/test_regress/t/t_mod_automatic.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_mod_automatic.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_mod_automatic.v b/test_regress/t/t_mod_automatic.v new file mode 100644 index 000000000..c3ffb868a --- /dev/null +++ b/test_regress/t/t_mod_automatic.v @@ -0,0 +1,47 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module automatic t(/*AUTOARG*/); + + task static accum_s(input integer value, output integer result); + static int acc = 1; + acc = acc + value; + result = acc; + endtask + + task accum_a(input integer value, output integer result); + int acc = 1; // automatic + acc = acc + value; + result = acc; + endtask + + integer value; + + reg failed = 0; // Static + + initial begin + accum_s(2, value); + $display("%d", value); + if (value !== 3) failed = 1; + + accum_s(3, value); + $display("%d", value); + if (value !== 6) failed = 1; + + accum_a(2, value); + $display("%d", value); + if (value !== 3) failed = 1; + + accum_a(3, value); + $display("%d", value); + if (value !== 4) failed = 1; + + if (failed) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From d4a8cbb1d6f5c5c6fe58423d5139cf7e2f27a242 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Nov 2024 08:00:43 -0500 Subject: [PATCH 071/171] Fix `function fork...join_none` regression with unknown type (#4449). --- Changes | 1 + src/V3EmitCFunc.h | 2 +- src/V3SchedTiming.cpp | 1 - test_regress/t/t_timing_func_join.py | 18 +++++++++++++++++ test_regress/t/t_timing_func_join.v | 29 ++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_timing_func_join.py create mode 100644 test_regress/t/t_timing_func_join.v diff --git a/Changes b/Changes index f0d5947e2..f1863246f 100644 --- a/Changes +++ b/Changes @@ -28,6 +28,7 @@ Verilator 5.031 devel * Add error on `solve before` or soft constraints of `randc` variable. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). +* Fix `function fork...join_none` regression with unknown type (#4449). * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index 389b5d012..a0eca3cd1 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -354,7 +354,7 @@ public: * executing in the wrong path to make verilator-generated code * run faster. */ - puts("auto &vlSelfRef = std::ref(*vlSelf).get();\n"); + puts("auto& vlSelfRef = std::ref(*vlSelf).get();\n"); } if (nodep->initsp()) { diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp index 0532ba998..13e2f0b88 100644 --- a/src/V3SchedTiming.cpp +++ b/src/V3SchedTiming.cpp @@ -422,7 +422,6 @@ void transformForks(AstNetlist* const netlistp) { void visit(AstExprStmt* nodep) override { iterateChildren(nodep); } //-------------------- - void visit(AstNodeExpr*) override {} // Accelerate void visit(AstNode* nodep) override { iterateChildren(nodep); } public: diff --git a/test_regress/t/t_timing_func_join.py b/test_regress/t/t_timing_func_join.py new file mode 100755 index 000000000..671072f97 --- /dev/null +++ b/test_regress/t/t_timing_func_join.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--binary']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_timing_func_join.v b/test_regress/t/t_timing_func_join.v new file mode 100644 index 000000000..e8b6b6816 --- /dev/null +++ b/test_regress/t/t_timing_func_join.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t(/*AUTOARG*/); + function int fun(int val); + fork + $display("abc"); + $display("def"); + join_none // Although join is illegal, join_none legal (IEEE 1800-2023 13.4) + return val + 2; + endfunction + + task tsk(); + fork + $display("ghi"); + $display("jkl"); + join_none + endtask + + initial begin + $display("$d", fun(2)); + tsk(); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 32c789c355e552e46d05b472bebaf032541092ab Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Nov 2024 19:14:38 -0500 Subject: [PATCH 072/171] Commentary --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 5d4767137..56d925078 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ .. Github doesn't render images unless absolute URL .. Do not know of a conditional tag, "only: github" nor "github display" works -|badge1| |badge2| |badge3| |badge4| |badge5| |badge6| |badge7| |badge8| +|badge1| |badge2| |badge3| |badge4| |badge5| |badge6| |badge7| .. |badge1| image:: https://img.shields.io/badge/Website-Verilator.org-181717.svg :target: https://verilator.org @@ -15,7 +15,7 @@ :target: https://hub.docker.com/r/verilator/verilator .. |badge6| image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f :target: https://www.codacy.com/gh/verilator/verilator -.. |badge8| image:: https://github.com/verilator/verilator/workflows/build/badge.svg +.. |badge7| image:: https://github.com/verilator/verilator/workflows/build/badge.svg :target: https://github.com/verilator/verilator/actions?query=workflow%3Abuild From 8e82440a55a63b65397d443fc00c6659efd4b586 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Nov 2024 19:15:10 -0500 Subject: [PATCH 073/171] Fix extranous local:: error --- src/V3LinkDot.cpp | 56 ++++++++++++++------------ test_regress/t/t_package_local_bad.out | 3 -- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 5923fce82..1c6aaf93e 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2147,7 +2147,7 @@ class LinkDotResolveVisitor final : public VNVisitor { enum DotPosition : uint8_t { // Must match ascii() method below DP_NONE = 0, // Not under a DOT - DP_PACKAGE, // {package}:: DOT + DP_PACKAGE, // {package-or-class}:: DOT DP_FIRST, // {scope-or-var} DOT DP_SCOPE, // DOT... {scope-or-var} DOT DP_FINAL, // [DOT...] {var-or-func-or-dtype} with no following dots @@ -2814,7 +2814,7 @@ class LinkDotResolveVisitor final : public VNVisitor { bool allowFTask = false; bool staticAccess = false; if (m_ds.m_dotPos == DP_PACKAGE) { - // {package}::{a} + // {package-or-class}::{a} AstNodeModule* classOrPackagep = nullptr; expectWhat = "scope/variable/func"; allowScope = true; @@ -3179,20 +3179,37 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep, "ClassRef has unlinked class"); UASSERT_OBJ(m_statep->forPrimary() || !nodep->paramsp(), nodep, "class reference parameter not removed by V3Param"); - VL_RESTORER(m_ds); - VL_RESTORER(m_pinSymp); - // ClassRef's have pins, so track - if (nodep->classOrPackagep()) { - m_pinSymp = m_statep->getNodeSym(nodep->classOrPackagep()); + { + // ClassRef's have pins, so track + VL_RESTORER(m_ds); + VL_RESTORER(m_pinSymp); + + if (nodep->classOrPackagep()) { + m_pinSymp = m_statep->getNodeSym(nodep->classOrPackagep()); + } + AstClass* const refClassp = VN_CAST(nodep->classOrPackagep(), Class); + // Make sure any extends() are properly imported within referenced class + if (refClassp && !m_statep->forPrimary()) classExtendImport(refClassp); + + m_ds.init(m_curSymp); + UINFO(4, indent() << "(Backto) Link ClassOrPackageRef: " << nodep << endl); + iterateChildren(nodep); + + AstClass* const modClassp = VN_CAST(m_modp, Class); + if (m_statep->forPrimary() && refClassp && !nodep->paramsp() + && nodep->classOrPackagep()->hasGParam() + // Don't warn on typedefs, which are hard to know if there's a param somewhere + // buried + && VN_IS(nodep->classOrPackageNodep(), Class) + // References to class:: within class itself are OK per IEEE (UVM does this) + && modClassp != refClassp) { + nodep->v3error( + "Reference to parameterized class without #() (IEEE 1800-2023 8.25.1)\n" + << nodep->warnMore() << "... Suggest use '" + << nodep->classOrPackageNodep()->prettyName() << "#()'"); + } } - AstClass* const refClassp = VN_CAST(nodep->classOrPackagep(), Class); - // Make sure any extends() are properly imported within referenced class - if (refClassp && !m_statep->forPrimary()) classExtendImport(refClassp); - - m_ds.init(m_curSymp); - UINFO(4, indent() << "(Backto) Link ClassOrPackageRef: " << nodep << endl); - iterateChildren(nodep); if (nodep->name() == "local::") { if (!m_randSymp) { @@ -3202,17 +3219,6 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } } - AstClass* const modClassp = VN_CAST(m_modp, Class); - if (m_statep->forPrimary() && refClassp && !nodep->paramsp() - && nodep->classOrPackagep()->hasGParam() - // Don't warn on typedefs, which are hard to know if there's a param somewhere buried - && VN_IS(nodep->classOrPackageNodep(), Class) - // References to class:: within class itself are OK per IEEE (UVM does this) - && modClassp != refClassp) { - nodep->v3error("Reference to parameterized class without #() (IEEE 1800-2023 8.25.1)\n" - << nodep->warnMore() << "... Suggest use '" - << nodep->classOrPackageNodep()->prettyName() << "#()'"); - } } void visit(AstConstraintRef* nodep) override { if (nodep->user3SetOnce()) return; diff --git a/test_regress/t/t_package_local_bad.out b/test_regress/t/t_package_local_bad.out index e219c46a2..8a3dbab30 100644 --- a/test_regress/t/t_package_local_bad.out +++ b/test_regress/t/t_package_local_bad.out @@ -1,7 +1,4 @@ %Error: t/t_package_local_bad.v:9:16: Illegal 'local::' outside 'randomize() with' (IEEE 1800-2023 18.7.1) 9 | $display(local::x); | ^~~~~ -%Error: t/t_package_local_bad.v:9:23: Can't find definition of scope/variable/func: 'x' - 9 | $display(local::x); - | ^ %Error: Exiting due to From 904be103df794057d9df55889c41104146ba92d5 Mon Sep 17 00:00:00 2001 From: Greg Davill Date: Thu, 14 Nov 2024 22:55:58 +1030 Subject: [PATCH 074/171] Support parameter names in pattern initialization (#5593) (#5596) --- docs/CONTRIBUTORS | 1 + src/V3AstNodeExpr.h | 3 ++- src/V3LinkDot.cpp | 18 ++++++++++++++ src/V3Width.cpp | 3 +++ test_regress/t/t_lparam_pattern_init.py | 18 ++++++++++++++ test_regress/t/t_lparam_pattern_init.v | 33 +++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_lparam_pattern_init.py create mode 100644 test_regress/t/t_lparam_pattern_init.v diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index f3913b510..76cca1e81 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -65,6 +65,7 @@ Gijs Burghoorn Glen Gibb Gökçe Aydos Graham Rushton +Greg Davill Guokai Chen Gus Smith Gustav Svensk diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index a883caa2f..27a8457ac 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1728,11 +1728,12 @@ public: class AstPatMember final : public AstNodeExpr { // Verilog '{a} or '{a{b}} // Parents: AstPattern - // Children: expression, AstPattern, replication count + // Children: expression, AstPattern, replication count, decoded nodep if TEXT // Expression to assign or another AstPattern (list if replicated) // @astgen op1 := lhssp : List[AstNodeExpr] // @astgen op2 := keyp : Optional[AstNode] // @astgen op3 := repp : Optional[AstNodeExpr] // replication count, or nullptr for count 1 + // @astgen op4 := varrefp : Optional[AstNodeExpr] // Decoded variable if TEXT bool m_default = false; public: diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 1c6aaf93e..722bf54f8 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2744,6 +2744,24 @@ class LinkDotResolveVisitor final : public VNVisitor { m_inSens = true; iterateChildren(nodep); } + void visit(AstPatMember* nodep) override { + LINKDOT_VISIT_START(); + if (nodep->varrefp()) return; // only do this mapping once + // If we have a TEXT token as our key, lookup if it's a LPARAM + if (AstText* const textp = VN_CAST(nodep->keyp(), Text)) { + UINFO(9, indent() << "visit " << nodep << endl); + UINFO(9, indent() << " " << textp << endl); + // Lookup + if (VSymEnt* const foundp = m_curSymp->findIdFallback(textp->text())) { + if (AstVar* const varp = VN_CAST(foundp->nodep(), Var)) { + // Attach found Text reference to PatMember + nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ}); + UINFO(9, indent() << " new " << nodep->varrefp() << endl); + } + } + } + iterateChildren(nodep); + } void visit(AstParseRef* nodep) override { if (nodep->user3SetOnce()) return; LINKDOT_VISIT_START(); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index d302ac4c7..23d77fae6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -7824,8 +7824,11 @@ class WidthVisitor final : public VNVisitor { for (AstPatMember* patp = VN_AS(nodep->itemsp(), PatMember); patp; patp = VN_AS(patp->nextp(), PatMember)) { if (patp->keyp()) { + if (patp->varrefp()) V3Const::constifyParamsEdit(patp->varrefp()); if (const AstConst* const constp = VN_CAST(patp->keyp(), Const)) { element = constp->toSInt(); + } else if (const AstConst* const constp = VN_CAST(patp->varrefp(), Const)) { + element = constp->toSInt(); } else { patp->keyp()->v3error("Assignment pattern key not supported/understood: " << patp->keyp()->prettyTypeName()); diff --git a/test_regress/t/t_lparam_pattern_init.py b/test_regress/t/t_lparam_pattern_init.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_lparam_pattern_init.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_lparam_pattern_init.v b/test_regress/t/t_lparam_pattern_init.v new file mode 100644 index 000000000..8abd72fc4 --- /dev/null +++ b/test_regress/t/t_lparam_pattern_init.v @@ -0,0 +1,33 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2010 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +module t (/*AUTOARG*/); + + localparam int unsigned SPI_INDEX = 0; + localparam int unsigned I2C_INDEX = 1; + localparam int unsigned TMR_INDEX = 4; + + localparam logic [31:0] AHB_ADDR[6] = '{ + SPI_INDEX: 32'h80001000, + I2C_INDEX: 32'h80002000, + TMR_INDEX: 32'h80003000, + default: '0}; + + initial begin + `checkh(AHB_ADDR[0], 32'h80001000); + `checkh(AHB_ADDR[1], 32'h80002000); + `checkh(AHB_ADDR[2], 32'h0); + `checkh(AHB_ADDR[3], 32'h0); + `checkh(AHB_ADDR[4], 32'h80003000); + `checkh(AHB_ADDR[5], 32'h0); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From c98744b914e8c2b662ecd1bb695c815c7c27bc53 Mon Sep 17 00:00:00 2001 From: Tom Manner Date: Thu, 14 Nov 2024 11:07:23 -0500 Subject: [PATCH 075/171] Internals: Fix `VerilatedContext::randSeed` comments (#5609) --- docs/CONTRIBUTORS | 1 + include/verilated.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 76cca1e81..9fc522b04 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -199,6 +199,7 @@ Steven Hugg Szymon Gizler Sören Tempel Teng Huang +Tom Manner Tim Hutt Tim Snyder Tobias Rosenkranz diff --git a/include/verilated.h b/include/verilated.h index aec79542b..76f84ff4c 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -546,9 +546,9 @@ public: /// 1 = Set all bits to one /// 2 = Randomize all bits void randReset(int val) VL_MT_SAFE; - /// Set default random seed, 0 = seed it automatically - int randSeed() const VL_MT_SAFE { return m_s.m_randSeed; } /// Return default random seed + int randSeed() const VL_MT_SAFE { return m_s.m_randSeed; } + /// Set default random seed, 0 = seed it automatically void randSeed(int val) VL_MT_SAFE; /// Return statistic: CPU time delta from model created until now From 81ac386a4ae57a84bf1dfd14c084144fe9579491 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 14 Nov 2024 21:05:59 -0500 Subject: [PATCH 076/171] Tests: Renames --- .../t/{t_lparam_pattern_init.py => t_param_pattern_init.py} | 0 .../t/{t_lparam_pattern_init.v => t_param_pattern_init.v} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test_regress/t/{t_lparam_pattern_init.py => t_param_pattern_init.py} (100%) rename test_regress/t/{t_lparam_pattern_init.v => t_param_pattern_init.v} (100%) diff --git a/test_regress/t/t_lparam_pattern_init.py b/test_regress/t/t_param_pattern_init.py similarity index 100% rename from test_regress/t/t_lparam_pattern_init.py rename to test_regress/t/t_param_pattern_init.py diff --git a/test_regress/t/t_lparam_pattern_init.v b/test_regress/t/t_param_pattern_init.v similarity index 100% rename from test_regress/t/t_lparam_pattern_init.v rename to test_regress/t/t_param_pattern_init.v From 9bde98e91205e7662f1b333caff1369ad7756327 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 14 Nov 2024 21:07:45 -0500 Subject: [PATCH 077/171] Commentary --- docs/guide/exe_verilator.rst | 15 ++++++++------- src/V3Error.h | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index ff680e481..87cd928c3 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1766,18 +1766,19 @@ Summary: ``-Wwarn-CASEX`` ``-Wwarn-CASTCONST`` ``-Wwarn-CMPCONST`` ``-Wwarn-COLONPLUS`` ``-Wwarn-IMPLICIT`` ``-Wwarn-IMPLICITSTATIC`` ``-Wwarn-LATCH`` ``-Wwarn-MISINDENT`` ``-Wwarn-NEWERSTD`` - ``-Wwarn-PINMISSING`` ``-Wwarn-REALCVT`` ``-Wwarn-STATICVAR`` - ``-Wwarn-UNSIGNED`` ``-Wwarn-WIDTHTRUNC`` ``-Wwarn-WIDTHEXPAND`` - ``-Wwarn-WIDTHXZEXPAND``. + ``-Wwarn-PREPROCZERO`` ``-Wwarn-PINMISSING`` ``-Wwarn-REALCVT`` + ``-Wwarn-STATICVAR`` ``-Wwarn-UNSIGNED`` ``-Wwarn-WIDTHTRUNC`` + ``-Wwarn-WIDTHEXPAND`` ``-Wwarn-WIDTHXZEXPAND``. .. option:: -Wwarn-style Enable all code style-related warning messages. This is equivalent to - ``-Wwarn-ASSIGNDLY`` ``-Wwarn-DECLFILENAME`` ``-Wwarn-DEFPARAM`` - ``-Wwarn-EOFNEWLINE`` ``-Wwarn-GENUNNAMED`` ``-Wwarn-INCABSPATH`` + ``-Wwarn-ASSIGNDLY`` ``-Wwarn-BLKSEQ`` ``-Wwarn-DECLFILENAME`` + ``-Wwarn-DEFPARAM`` ``-Wwarn-EOFNEWLINE`` ``-Wwarn-GENUNNAMED`` + ``-Wwarn-IMPORTSTAR`` ``-Wwarn-INCABSPATH`` ``-Wwarn-PINCONNECTEMPTY`` ``-Wwarn-PINNOCONNECT`` ``-Wwarn-SYNCASYNCNET`` ``-Wwarn-UNDRIVEN`` - ``-Wwarn-UNUSEDGENVAR`` ``-Wwarn-UNUSEDPARAM`` ``-Wwarn-UNUSEDSIGNAL`` - ``-Wwarn-VARHIDDEN``. + ``-Wwarn-UNUSEDGENVAR`` ``-Wwarn-UNUSEDLOOP`` ``-Wwarn-UNUSEDPARAM`` + ``-Wwarn-UNUSEDSIGNAL`` ``-Wwarn-VARHIDDEN``. .. option:: --x-assign 0 diff --git a/src/V3Error.h b/src/V3Error.h index e2b669be3..d0a2bf77f 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -254,7 +254,7 @@ public: // Warnings that are style only bool styleError() const VL_MT_SAFE { return (m_e == ASSIGNDLY // More than style, but for backward compatibility - || m_e == BLKSEQ || m_e == DEFPARAM || m_e == DECLFILENAME || m_e == EOFNEWLINE + || m_e == BLKSEQ || m_e == DECLFILENAME || m_e == DEFPARAM || m_e == EOFNEWLINE || m_e == GENUNNAMED || m_e == IMPORTSTAR || m_e == INCABSPATH || m_e == PINCONNECTEMPTY || m_e == PINNOCONNECT || m_e == SYNCASYNCNET || m_e == UNDRIVEN || m_e == UNUSEDGENVAR || m_e == UNUSEDLOOP From 5470cf9fa92caafc5be8952472cbd24f8b050bd9 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 15 Nov 2024 16:45:06 +0100 Subject: [PATCH 078/171] Support randomize size constraints with restrictions (#5582 partial) (#5611) --- include/verilated_types.h | 1 + src/V3AstNodes.cpp | 1 + src/V3Randomize.cpp | 97 ++++++++++++++++++- .../t/t_randomize_method_types_unsup.out | 17 +++- .../t/t_randomize_method_types_unsup.v | 14 ++- test_regress/t/t_randomize_queue_size.py | 21 ++++ test_regress/t/t_randomize_queue_size.v | 85 ++++++++++++++++ test_regress/t/uvm/uvm_pkg_todo.svh | 8 +- 8 files changed, 229 insertions(+), 15 deletions(-) create mode 100755 test_regress/t/t_randomize_queue_size.py create mode 100755 test_regress/t/t_randomize_queue_size.v diff --git a/include/verilated_types.h b/include/verilated_types.h index 773b20212..2e8af51ee 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -570,6 +570,7 @@ public: m_deque.resize(size, atDefault()); } } + void resize(size_t size) { m_deque.resize(size, atDefault()); } // function void q.push_front(value) void push_front(const T_Value& value) { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 54987e853..fbb5eb3de 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2903,6 +2903,7 @@ void AstCMethodHard::setPurity() { {"r_xor", true}, {"renew", false}, {"renew_copy", false}, + {"resize", false}, {"resume", false}, {"reverse", false}, {"rsort", false}, diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 9b059d512..0390e3cbc 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -606,6 +606,12 @@ class ConstraintExprVisitor final : public VNVisitor { // VISITORS void visit(AstNodeVarRef* nodep) override { AstVar* const varp = nodep->varp(); + if (varp->user4p()) { + varp->user4p()->v3warn( + CONSTRAINTIGN, + "Size constraint combined with element constraint may not work correctly"); + } + AstNodeModule* const classOrPackagep = nodep->classOrPackagep(); const RandomizeMode randMode = {.asInt = varp->user1()}; if (!randMode.usesMode && editFormat(nodep)) return; @@ -1132,7 +1138,9 @@ class RandomizeVisitor final : public VNVisitor { // AstClass::user2p() -> AstVar*. Rand mode state variable // AstVar::user3() -> bool. Handled in constraints // AstClass::user3p() -> AstVar*. Constrained randomizer variable + // AstConstraint::user3p() -> AstTask*. Pointer to resize procedure // AstClass::user4p() -> AstVar*. Constraint mode state variable + // AstVar::user4p() -> AstVar*. Size variable for constrained queues // VNUser1InUse m_inuser1; (Allocated for use in RandomizeMarkVisitor) // VNUser2InUse m_inuser2; (Allocated for use in RandomizeMarkVisitor) const VNUser3InUse m_inuser3; @@ -1150,6 +1158,7 @@ class RandomizeVisitor final : public VNVisitor { size_t m_enumValueTabCount = 0; // Number of tables with enum values created int m_randCaseNum = 0; // Randcase number within a module for var naming std::map m_randcDtypes; // RandC data type deduplication + AstConstraint* m_constraintp = nullptr; // Current constraint // METHODS void createRandomGenerator(AstClass* const classp) { @@ -1180,6 +1189,17 @@ class RandomizeVisitor final : public VNVisitor { m_memberMap.insert(classp, setupAllTaskp); return setupAllTaskp; } + AstTask* getCreateAggrResizeTask(AstClass* const classp) { + static const char* const name = "__Vresize_constrained_arrays"; + AstTask* resizeTaskp = VN_AS(m_memberMap.findMember(classp, name), Task); + if (resizeTaskp) return resizeTaskp; + resizeTaskp = new AstTask{classp->fileline(), name, nullptr}; + resizeTaskp->classMethod(true); + resizeTaskp->isVirtual(true); + classp->addMembersp(resizeTaskp); + m_memberMap.insert(classp, resizeTaskp); + return resizeTaskp; + } AstVar* getCreateRandModeVar(AstClass* const classp) { if (classp->user2p()) return VN_AS(classp->user2p(), Var); if (AstClassExtends* const extendsp = classp->extendsp()) { @@ -1281,8 +1301,7 @@ class RandomizeVisitor final : public VNVisitor { FileLine* fl = modeVarp->fileline(); AstCMethodHard* const dynarrayNewp = new AstCMethodHard{fl, new AstVarRef{fl, modeVarModp, modeVarp, VAccess::WRITE}, - "renew_copy", new AstConst{fl, modeCount}}; - dynarrayNewp->addPinsp(new AstVarRef{fl, modeVarModp, modeVarp, VAccess::READ}); + "resize", new AstConst{fl, modeCount}}; dynarrayNewp->dtypeSetVoid(); AstNodeFTask* const newp = VN_AS(m_memberMap.findMember(classp, "new"), NodeFTask); UASSERT_OBJ(newp, classp, "No new() in class"); @@ -1565,6 +1584,13 @@ class RandomizeVisitor final : public VNVisitor { nodep->addMembersp(taskp); return taskp; } + AstTask* newResizeConstrainedArrayTask(AstClass* const nodep, const std::string& name) { + AstTask* const taskp + = new AstTask{nodep->fileline(), name + "_resize_constrained_array", nullptr}; + taskp->classMethod(true); + nodep->addMembersp(taskp); + return taskp; + } AstNodeStmt* implementConstraintsClear(FileLine* const fileline, AstVar* const genp) { AstCMethodHard* const clearp = new AstCMethodHard{ fileline, @@ -1898,6 +1924,15 @@ class RandomizeVisitor final : public VNVisitor { setupAllTaskp->addStmtsp(setupTaskRefp->makeStmt()); + if (AstTask* const resizeTaskp = VN_CAST(constrp->user3p(), Task)) { + AstTask* const resizeAllTaskp = getCreateAggrResizeTask(nodep); + AstTaskRef* const resizeTaskRefp + = new AstTaskRef{constrp->fileline(), resizeTaskp->name(), nullptr}; + resizeTaskRefp->taskp(resizeTaskp); + resizeTaskRefp->classOrPackagep(classp); + resizeAllTaskp->addStmtsp(resizeTaskRefp->makeStmt()); + } + ConstraintExprVisitor{m_memberMap, constrp->itemsp(), nullptr, genp, randModeVarp}; if (constrp->itemsp()) { taskp->addStmtsp(wrapIfConstraintMode( @@ -1933,6 +1968,13 @@ class RandomizeVisitor final : public VNVisitor { AstVarRef* const fvarRefp = new AstVarRef{fl, fvarp, VAccess::WRITE}; randomizep->addStmtsp(new AstAssign{fl, fvarRefp, beginValp}); + if (AstTask* const resizeAllTaskp + = VN_AS(m_memberMap.findMember(nodep, "__Vresize_constrained_arrays"), Task)) { + AstTaskRef* const resizeTaskRefp = new AstTaskRef{fl, resizeAllTaskp->name(), nullptr}; + resizeTaskRefp->taskp(resizeAllTaskp); + randomizep->addStmtsp(resizeTaskRefp->makeStmt()); + } + AstFunc* const basicRandomizep = V3Randomize::newRandomizeFunc(m_memberMap, nodep, "__Vbasic_randomize"); addBasicRandomizeBody(basicRandomizep, nodep, randModeVarp); @@ -2161,6 +2203,57 @@ class RandomizeVisitor final : public VNVisitor { UINFO(9, "Added `%s` randomization procedure"); VL_DO_DANGLING(withp->deleteTree(), withp); } + void visit(AstConstraint* nodep) override { + VL_RESTORER(m_constraintp); + m_constraintp = nodep; + iterateChildren(nodep); + } + void visit(AstCMethodHard* nodep) override { + iterateChildren(nodep); + FileLine* const fl = nodep->fileline(); + if (m_constraintp && nodep->fromp()->user1() && nodep->name() == "size") { + AstClass* const classp = VN_AS(m_modp, Class); + AstVarRef* const queueVarRefp = VN_CAST(nodep->fromp(), VarRef); + if (!queueVarRefp) { + // Warning from ConstraintExprVisitor will be thrown + return; + } + AstVar* const queueVarp = queueVarRefp->varp(); + AstVar* sizeVarp = VN_CAST(queueVarp->user4p(), Var); + if (!sizeVarp) { + sizeVarp = new AstVar{fl, VVarType::BLOCKTEMP, "__V" + queueVarp->name() + "_size", + nodep->findSigned32DType()}; + classp->addMembersp(sizeVarp); + m_memberMap.insert(classp, sizeVarp); + sizeVarp->user2p(classp); + + queueVarp->user4p(sizeVarp); + + AstTask* resizerTaskp = VN_AS(m_constraintp->user3p(), Task); + if (!resizerTaskp) { + resizerTaskp = newResizeConstrainedArrayTask(classp, m_constraintp->name()); + m_constraintp->user3p(resizerTaskp); + } + AstCMethodHard* const resizep + = new AstCMethodHard{fl, nodep->fromp()->unlinkFrBack(), "resize", + new AstVarRef{fl, sizeVarp, VAccess::READ}}; + resizep->dtypep(nodep->findVoidDType()); + resizerTaskp->addStmtsp(new AstStmtExpr{fl, resizep}); + + // Since size variable is signed int, we need additional constraint + // to make sure it is always >= 0. + AstVarRef* const sizeVarRefp = new AstVarRef{fl, sizeVarp, VAccess::READ}; + sizeVarRefp->user1(true); + AstGteS* const sizeGtep = new AstGteS{fl, sizeVarRefp, new AstConst{fl, 0}}; + sizeGtep->user1(true); + m_constraintp->addItemsp(new AstConstraintExpr{fl, sizeGtep}); + } + AstVarRef* const sizeVarRefp = new AstVarRef{fl, sizeVarp, VAccess::READ}; + sizeVarRefp->user1(true); + nodep->replaceWith(sizeVarRefp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + } + } void visit(AstNodeStmt* nodep) override { VL_RESTORER(m_stmtp); m_stmtp = nodep; diff --git a/test_regress/t/t_randomize_method_types_unsup.out b/test_regress/t/t_randomize_method_types_unsup.out index 2526171bc..4b53e95ef 100644 --- a/test_regress/t/t_randomize_method_types_unsup.out +++ b/test_regress/t/t_randomize_method_types_unsup.out @@ -1,10 +1,17 @@ -%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:13:32: Unsupported: randomizing this expression, treating as state - 13 | constraint dynsize { dynarr.size < 20; } - | ^~~~ +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:17:17: Unsupported: randomizing this expression, treating as state + 17 | dynarr[1].size < 10; + | ^~~~ ... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest ... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message. -%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:10:13: Unsupported: random member variable with the type of the containing class +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:21:9: Size constraint combined with element constraint may not work correctly + : ... note: In instance 't' + 21 | q.size < 5; + | ^~~~ +%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:11:13: Unsupported: random member variable with the type of the containing class : ... note: In instance 't' - 10 | rand Cls cls; + 11 | rand Cls cls; | ^~~ +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:33:43: Unsupported: randomizing this expression, treating as state + 33 | res = obj.randomize() with { dynarr.size > 2; }; + | ^~~~ %Error: Exiting due to diff --git a/test_regress/t/t_randomize_method_types_unsup.v b/test_regress/t/t_randomize_method_types_unsup.v index 8fbb96f52..b68abf141 100644 --- a/test_regress/t/t_randomize_method_types_unsup.v +++ b/test_regress/t/t_randomize_method_types_unsup.v @@ -6,12 +6,21 @@ class Cls; rand int assocarr[string]; - rand int dynarr[]; + rand int dynarr[][]; + rand int q[$]; rand Cls cls; rand int i; int st; - constraint dynsize { dynarr.size < 20; } + constraint dynsize { + dynarr.size < 20; + dynarr.size > 0; + dynarr[1].size < 10; + } constraint statedep { i < st + 2; } + constraint q_size_elem { + q.size < 5; + q[i] < 10; + } endclass module t (/*AUTOARG*/); @@ -21,5 +30,6 @@ module t (/*AUTOARG*/); initial begin obj = new; res = obj.randomize(); + res = obj.randomize() with { dynarr.size > 2; }; end endmodule diff --git a/test_regress/t/t_randomize_queue_size.py b/test_regress/t/t_randomize_queue_size.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_randomize_queue_size.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_queue_size.v b/test_regress/t/t_randomize_queue_size.v new file mode 100755 index 000000000..f1429f642 --- /dev/null +++ b/test_regress/t/t_randomize_queue_size.v @@ -0,0 +1,85 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +`define check_rand(cl, field, cond) \ +begin \ + longint prev_result; \ + int ok = 0; \ + if (!bit'(cl.randomize())) $stop; \ + prev_result = longint'(field); \ + if (!(cond)) $stop; \ + repeat(9) begin \ + longint result; \ + if (!bit'(cl.randomize())) $stop; \ + result = longint'(field); \ + if (!(cond)) $stop; \ + if (result != prev_result) ok = 1; \ + prev_result = result; \ + end \ + if (ok != 1) $stop; \ +end + +class Foo; + rand int q[$]; + rand int q2[$][$]; + int x = 1; + constraint c { + q.size() == 15; + q2.size() == 10; + } +endclass + +class Bar; + rand int q[$]; + rand int min_size; + rand int q2[$]; + constraint c { + min_size > 2; + q.size() >= min_size; + q.size() < 10; + }; + constraint c2 { + q2.size() < 7; + } +endclass + +class Baz; + rand Foo foo_arr[]; + constraint c_foo { + foo_arr.size == 7; + } +endclass + +module t; + initial begin + Foo foo = new; + Bar bar = new; + Baz baz = new; + + void'(foo.randomize()); + if (foo.q.size() != 15) $stop; + if (foo.q2.size() != 10) $stop; + + `check_rand(bar, bar.q.size(), bar.q.size() > 2 && bar.q.size() < 10); + `check_rand(bar, bar.q2.size(), bar.q2.size() < 7); + + baz.foo_arr = new[4]; + for (int i = 0; i < 4; i++) baz.foo_arr[i] = new; + baz.foo_arr[2].x = 2; + void'(baz.randomize()); + + if (baz.foo_arr.size() != 7) $stop; + for (int i = 0; i < 4; i++) + if (baz.foo_arr[i] == null) $stop; + for (int i = 4; i < 7; i++) + if (baz.foo_arr[i] != null) $stop; + if (baz.foo_arr[2].x != 2) $stop; + `check_rand(baz, baz.foo_arr[1].q[5], 1'b1); + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/uvm/uvm_pkg_todo.svh b/test_regress/t/uvm/uvm_pkg_todo.svh index 0ef277ddb..65c2d0b3d 100644 --- a/test_regress/t/uvm/uvm_pkg_todo.svh +++ b/test_regress/t/uvm/uvm_pkg_todo.svh @@ -22444,9 +22444,7 @@ class uvm_reg_item extends uvm_sequence_item; uvm_elem_kind_e element_kind; uvm_object element; rand uvm_access_e kind; - //TODO issue-5582 - Rand constraint with .size - //TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state - /*rand*/ uvm_reg_data_t value[]; + rand uvm_reg_data_t value[]; constraint max_values { value.size() > 0 && value.size() < 1000; } rand uvm_reg_addr_t offset; uvm_status_e status; @@ -26866,9 +26864,7 @@ class uvm_reg_fifo extends uvm_reg; local uvm_reg_field value; local int m_set_cnt; local int unsigned m_size; - //TODO issue-5582 - Rand constraint with .size - //TODO %Warning-CONSTRAINTIGN: t/t_uvm_pkg_todo.vh:#:#: Unsupported: randomizing this expression, treating as state - /*rand*/ uvm_reg_data_t fifo[$]; + rand uvm_reg_data_t fifo[$]; constraint valid_fifo_size { fifo.size() <= m_size; } From 58dae8f93152510dff6a892c22f37cd9e07cc185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Thu, 21 Nov 2024 13:05:18 +0100 Subject: [PATCH 079/171] Fix clang_check_attributes TypeError when accessing compilation database (#5622) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bartłomiej Chmiel --- nodist/clang_check_attributes | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/nodist/clang_check_attributes b/nodist/clang_check_attributes index 34714de5b..b79c49a1a 100755 --- a/nodist/clang_check_attributes +++ b/nodist/clang_check_attributes @@ -38,6 +38,7 @@ else: def __getattr__(cls, name: str) -> clang.cindex.CursorKind: return getattr(clang.cindex.CursorKind, name) + # pylint: disable-next=invalid-enum-extension class CursorKind(clang.cindex.CursorKind, metaclass=CursorKindMeta): pass @@ -1145,10 +1146,14 @@ def main(): for refid, file in enumerate(cmdline.file): filename = os.path.abspath(file) root = default_compilation_root - cxxflags = [] + cxxflags = common_cxxflags[:] if compdb: entry = compdb.getCompileCommands(filename) - entry_list = list(entry) + if entry is None: + print(f"%Error: reading compile commands failed: {filename}", file=sys.stderr) + entry_list = [] + else: + entry_list = list(entry) # Compilation database can contain multiple entries for single file, # e.g. when it has been updated by appending new entries. # Use last entry for the file, if it exists, as it is the newest one. @@ -1160,9 +1165,7 @@ def main(): # compiler executable name/path. CIndex (libclang) always # implicitly prepends executable name, so it shouldn't be passed # here. - cxxflags = common_cxxflags + entry_args[1:] - else: - cxxflags = common_cxxflags[:] + cxxflags.extend(entry_args[1:]) compile_command = CompileCommand(refid, filename, cxxflags, root) compile_commands_list.append(compile_command) From ae990ebcda95fa0203d08e7e5d41028ab3155f8d Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 22 Nov 2024 14:47:14 +0100 Subject: [PATCH 080/171] Add warning on global constraints (#5625) --- src/V3Randomize.cpp | 36 +++++++------- test_regress/t/t_constraint_state.v | 47 +++++++++++++++++-- .../t/t_randomize_method_types_unsup.out | 19 ++++---- .../t/t_randomize_method_types_unsup.v | 10 ++++ 4 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 0390e3cbc..c920cc1cb 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -438,26 +438,16 @@ class RandomizeMarkVisitor final : public VNVisitor { if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep); - if (!nodep->varp()->rand().isRandomizable()) return; - for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); - backp = backp->backp()) - backp->user1(true); + if (nodep->varp()->rand().isRandomizable()) nodep->user1(true); } void visit(AstMemberSel* nodep) override { if (!m_constraintExprGenp) return; - if (VN_IS(nodep->fromp(), LambdaArgRef)) { - if (!nodep->varp()->rand().isRandomizable()) return; - for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); - backp = backp->backp()) - backp->user1(true); - } - } - void visit(AstArraySel* nodep) override { - if (!m_constraintExprGenp) return; - for (AstNode* backp = nodep; backp != m_constraintExprGenp && !backp->user1(); - backp = backp->backp()) - backp->user1(true); iterateChildrenConst(nodep); + // Member select are randomized when both object and member are marked as rand. + // Variable references in with clause are converted to member selects and their from() is + // of type AstLambdaArgRef. They are randomized too. + const bool randObject = nodep->fromp()->user1() || VN_IS(nodep->fromp(), LambdaArgRef); + nodep->user1(randObject && nodep->varp()->rand().isRandomizable()); } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_modp); @@ -473,6 +463,14 @@ class RandomizeMarkVisitor final : public VNVisitor { iterateChildrenConst(nodep); } + void visit(AstNodeExpr* nodep) override { + iterateChildrenConst(nodep); + if (!m_constraintExprGenp) return; + nodep->user1((nodep->op1p() && nodep->op1p()->user1()) + || (nodep->op2p() && nodep->op2p()->user1()) + || (nodep->op3p() && nodep->op3p()->user1()) + || (nodep->op4p() && nodep->op4p()->user1())); + } void visit(AstNode* nodep) override { iterateChildrenConst(nodep); } public: @@ -735,6 +733,12 @@ class ConstraintExprVisitor final : public VNVisitor { handle.relink(indexp); editSMT(nodep, nodep->fromp(), indexp); } + void visit(AstMemberSel* nodep) override { + if (nodep->user1()) { + nodep->v3warn(CONSTRAINTIGN, "Global constraints ignored (unsupported)"); + } + editFormat(nodep); + } void visit(AstSFormatF* nodep) override {} void visit(AstStmtExpr* nodep) override {} void visit(AstConstraintIf* nodep) override { diff --git a/test_regress/t/t_constraint_state.v b/test_regress/t/t_constraint_state.v index 799dea166..f89f2819a 100644 --- a/test_regress/t/t_constraint_state.v +++ b/test_regress/t/t_constraint_state.v @@ -4,12 +4,50 @@ // any use, without warranty, 2023 by Antmicro Ltd. // SPDX-License-Identifier: CC0-1.0 + +`define check_rand(cl, field, cond) \ +begin \ + longint prev_result; \ + int ok = 0; \ + if (!bit'(cl.randomize())) $stop; \ + prev_result = longint'(field); \ + if (!(cond)) $stop; \ + repeat(9) begin \ + longint result; \ + if (!bit'(cl.randomize())) $stop; \ + result = longint'(field); \ + if (!(cond)) $stop; \ + if (result != prev_result) ok = 1; \ + prev_result = result; \ + end \ + if (ok != 1) $stop; \ +end + +class Foo; + int x; +endclass + +class Bar; + rand int y; +endclass + class Packet; rand int rf; int state; + rand int a; + rand Foo foo; + Bar bar; - constraint c { rf == state; } + constraint c1 { rf == state; } + constraint c2 { a > foo.x; a < bar.y; } + function new(int s, int x, int y); + state = s; + foo = new; + foo.x = x; + bar = new; + bar.y = y; + endfunction endclass module t (/*AUTOARG*/); @@ -19,12 +57,15 @@ module t (/*AUTOARG*/); int v; initial begin - p = new; - p.state = 123; + p = new(123, 10, 20); v = p.randomize(); if (v != 1) $stop; if (p.rf != 123) $stop; + `check_rand(p, p.a, p.a > 10 && p.a < 20) + if (p.foo.x != 10) $stop; + if (p.bar.y != 20) $stop; + p.state = 234; v = p.randomize(); if (v != 1) $stop; diff --git a/test_regress/t/t_randomize_method_types_unsup.out b/test_regress/t/t_randomize_method_types_unsup.out index 4b53e95ef..4dd60a0a9 100644 --- a/test_regress/t/t_randomize_method_types_unsup.out +++ b/test_regress/t/t_randomize_method_types_unsup.out @@ -1,17 +1,20 @@ -%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:17:17: Unsupported: randomizing this expression, treating as state - 17 | dynarr[1].size < 10; +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:23:17: Unsupported: randomizing this expression, treating as state + 23 | dynarr[1].size < 10; | ^~~~ ... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest ... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message. -%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:21:9: Size constraint combined with element constraint may not work correctly +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:27:9: Size constraint combined with element constraint may not work correctly : ... note: In instance 't' - 21 | q.size < 5; + 27 | q.size < 5; | ^~~~ -%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:11:13: Unsupported: random member variable with the type of the containing class +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:31:10: Global constraints ignored (unsupported) + 31 | foo.x < y; + | ^ +%Error-UNSUPPORTED: t/t_randomize_method_types_unsup.v:15:13: Unsupported: random member variable with the type of the containing class : ... note: In instance 't' - 11 | rand Cls cls; + 15 | rand Cls cls; | ^~~ -%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:33:43: Unsupported: randomizing this expression, treating as state - 33 | res = obj.randomize() with { dynarr.size > 2; }; +%Warning-CONSTRAINTIGN: t/t_randomize_method_types_unsup.v:43:43: Unsupported: randomizing this expression, treating as state + 43 | res = obj.randomize() with { dynarr.size > 2; }; | ^~~~ %Error: Exiting due to diff --git a/test_regress/t/t_randomize_method_types_unsup.v b/test_regress/t/t_randomize_method_types_unsup.v index b68abf141..f100eeac9 100644 --- a/test_regress/t/t_randomize_method_types_unsup.v +++ b/test_regress/t/t_randomize_method_types_unsup.v @@ -4,12 +4,18 @@ // any use, without warranty, 2020 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +class Foo; + rand int x; +endclass + class Cls; rand int assocarr[string]; rand int dynarr[][]; rand int q[$]; rand Cls cls; rand int i; + rand Foo foo; + rand int y; int st; constraint dynsize { dynarr.size < 20; @@ -21,6 +27,9 @@ class Cls; q.size < 5; q[i] < 10; } + constraint global_constraint { + foo.x < y; + } endclass module t (/*AUTOARG*/); @@ -29,6 +38,7 @@ module t (/*AUTOARG*/); initial begin obj = new; + obj.foo = new; res = obj.randomize(); res = obj.randomize() with { dynarr.size > 2; }; end From ca31bcdbb67c87215b210c81dfc0df76ca59b29b Mon Sep 17 00:00:00 2001 From: sumpster Date: Sun, 24 Nov 2024 00:10:37 +0100 Subject: [PATCH 081/171] Tests: Fix solver help output detection case insensitive (#5626) (#5627) --- docs/CONTRIBUTORS | 1 + test_regress/driver.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 9fc522b04..8824b138f 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -196,6 +196,7 @@ Srinivasan Venkataramanan Stefan Wallentowitz Stephen Henry Steven Hugg +sumpster Szymon Gizler Sören Tempel Teng Huang diff --git a/test_regress/driver.py b/test_regress/driver.py index 0a4bc0610..d8a80a89a 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -180,7 +180,7 @@ class Capabilities: if Capabilities._cached_have_solver is None: out = VtOs.run_capture('(z3 --help || cvc5 --help || cvc4 --help) 2>/dev/null', check=False) - Capabilities._cached_have_solver = bool('Usage' in out) + Capabilities._cached_have_solver = bool('usage' in out.casefold()) return Capabilities._cached_have_solver @staticproperty From 24b5c641f5629763e05e3f676c6c407af6ed6235 Mon Sep 17 00:00:00 2001 From: sumpster Date: Sun, 24 Nov 2024 04:01:02 +0100 Subject: [PATCH 082/171] Fix array of struct member overwrites on member update (#5605) (#5618) (#5628) --- src/V3Unknown.cpp | 25 ++----------- .../t/t_struct_array_assignment_delayed.py | 18 ++++++++++ .../t/t_struct_array_assignment_delayed.v | 35 +++++++++++++++++++ 3 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 test_regress/t/t_struct_array_assignment_delayed.py create mode 100644 test_regress/t/t_struct_array_assignment_delayed.v diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index b68241674..f00b9620b 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -99,7 +99,7 @@ class UnknownVisitor final : public VNVisitor { AstNodeExpr* prep = nodep; // Scan back to put the condlvalue above all selects (IE top of the lvalue) - while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel)) { + while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel) || VN_IS(prep->backp(), StructSel)) { prep = VN_AS(prep->backp(), NodeExpr); } FileLine* const fl = nodep->fileline(); @@ -119,28 +119,7 @@ class UnknownVisitor final : public VNVisitor { = new AstVar{fl, VVarType::MODULETEMP, m_lvboundNames.get(prep), prep->dtypep()}; m_modp->addStmtsp(varp); AstNode* const abovep = prep->backp(); // Grab above point before we replace 'prep' - AstNode* currentStmtp = abovep; - while (currentStmtp && !VN_IS(currentStmtp, NodeStmt)) - currentStmtp = currentStmtp->backp(); - VNRelinker linkContext; - currentStmtp = currentStmtp->unlinkFrBackWithNext(&linkContext); - AstNodeExpr* const selExprp = prep->cloneTree(true); - AstNodeExpr* currentExprp = selExprp; - while (AstNodeExpr* itrSelExprp = VN_AS(currentExprp->op1p(), NodeExpr)) { - if (AstNodeVarRef* const selRefp = VN_CAST(itrSelExprp, NodeVarRef)) { - // Mark the variable reference as READ access to avoid assignment issues - selRefp->access(VAccess::READ); - break; - } - currentExprp = itrSelExprp; - } - // Before assigning the value to the temporary variable, first assign the current array - // element to it. This ensures any field modifications happen on the correct instance - // and prevents overwriting other fields. - AstNode* const newAssignp - = new AstAssign{fl, new AstVarRef{fl, varp, VAccess::WRITE}, selExprp}; - newAssignp->addNextStmt(currentStmtp, newAssignp); - linkContext.relink(newAssignp); + prep->replaceWith(new AstVarRef{fl, varp, VAccess::WRITE}); if (m_timingControlp) m_timingControlp->unlinkFrBack(); AstIf* const newp = new AstIf{ diff --git a/test_regress/t/t_struct_array_assignment_delayed.py b/test_regress/t/t_struct_array_assignment_delayed.py new file mode 100644 index 000000000..3476171ff --- /dev/null +++ b/test_regress/t/t_struct_array_assignment_delayed.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(timing_loop=True, verilator_flags2=["--timing"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_struct_array_assignment_delayed.v b/test_regress/t/t_struct_array_assignment_delayed.v new file mode 100644 index 000000000..1e4703c6c --- /dev/null +++ b/test_regress/t/t_struct_array_assignment_delayed.v @@ -0,0 +1,35 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by sumpster. +// SPDX-License-Identifier: CC0-1.0 + +module tb; + typedef struct { + logic a; + logic b; + } SimpleStruct; + + SimpleStruct s [1]; + + logic clock; + + always @(posedge clock) begin + for (int i = 0; i < 1; i++) begin + s[i].a <= 1; + s[i].b <= 0; + end + end + + initial begin + clock = 0; + s[0].a = 0; + s[0].b = 0; + + #1 clock = 1; + #1 if (s[0].a != 1) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 0d5fedce9234f916bce405b54f4ba00c67d7d03f Mon Sep 17 00:00:00 2001 From: github action Date: Sun, 24 Nov 2024 03:02:04 +0000 Subject: [PATCH 083/171] Apply 'make format' --- src/V3Unknown.cpp | 3 ++- test_regress/t/t_struct_array_assignment_delayed.py | 0 2 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 test_regress/t/t_struct_array_assignment_delayed.py diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index f00b9620b..e649c02cd 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -99,7 +99,8 @@ class UnknownVisitor final : public VNVisitor { AstNodeExpr* prep = nodep; // Scan back to put the condlvalue above all selects (IE top of the lvalue) - while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel) || VN_IS(prep->backp(), StructSel)) { + while (VN_IS(prep->backp(), NodeSel) || VN_IS(prep->backp(), Sel) + || VN_IS(prep->backp(), StructSel)) { prep = VN_AS(prep->backp(), NodeExpr); } FileLine* const fl = nodep->fileline(); diff --git a/test_regress/t/t_struct_array_assignment_delayed.py b/test_regress/t/t_struct_array_assignment_delayed.py old mode 100644 new mode 100755 From 7e9535381acbb0e72744d82433605c998564c8f4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 16 Nov 2024 09:22:38 -0500 Subject: [PATCH 084/171] Tests: Use VM_PREFIX --- test_regress/t/t_force_mid.cpp | 6 ++++-- test_regress/t/t_tri_top_en_out.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test_regress/t/t_force_mid.cpp b/test_regress/t/t_force_mid.cpp index 5afb7e5a3..ca91e6179 100644 --- a/test_regress/t/t_force_mid.cpp +++ b/test_regress/t/t_force_mid.cpp @@ -10,10 +10,12 @@ // OS header #include "verilatedos.h" // Generated header -#include "Vt_force_mid.h" +#include VM_PREFIX_INCLUDE // General headers #include "verilated.h" -std::unique_ptr topp; + +std::unique_ptr topp; + int main(int argc, char** argv) { uint64_t sim_time = 1100; const std::unique_ptr contextp{new VerilatedContext}; diff --git a/test_regress/t/t_tri_top_en_out.cpp b/test_regress/t/t_tri_top_en_out.cpp index 39735e8e0..9035ce61e 100644 --- a/test_regress/t/t_tri_top_en_out.cpp +++ b/test_regress/t/t_tri_top_en_out.cpp @@ -7,7 +7,7 @@ #include "verilated.h" #include "TestCheck.h" -#include "Vt_tri_top_en_out.h" +#include VM_PREFIX_INCLUDE #include @@ -18,7 +18,7 @@ int main(int argc, char** argv, char**) { const std::unique_ptr contextp{new VerilatedContext}; contextp->commandArgs(argc, argv); // Construct the Verilated model, from Vtop.h generated from Verilating - const std::unique_ptr topp{new Vt_tri_top_en_out{contextp.get()}}; + const std::unique_ptr topp{new VM_PREFIX{contextp.get()}}; // Initial input topp->drv_en = 0; From 749b0345df24db0b58f3d225e26139b01434ad9e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 23 Nov 2024 22:06:07 -0500 Subject: [PATCH 085/171] Commentary: Changes update --- Changes | 4 ++++ docs/guide/exe_verilator.rst | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Changes b/Changes index f1863246f..35974cbf0 100644 --- a/Changes +++ b/Changes @@ -16,6 +16,8 @@ Verilator 5.031 devel * Support queue's assignment `push_back/push_front('{})` (#5585) (#5586). [Yilou Wang] * Support basic constrained random for multi-dimensional dynamic array and queue (#5591). [Yilou Wang] * Support vpiDefName (#3906) (#5572). [Krzysztof Starecki] +* Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill] +* Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.] * Support `pure constraint`. * Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). * Add `--no-std-package` as subset-alias of `--no-std` (#5607). @@ -25,6 +27,7 @@ Verilator 5.031 devel * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] +* Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add error on `solve before` or soft constraints of `randc` variable. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). @@ -38,6 +41,7 @@ Verilator 5.031 devel * Fix duplicate scope identifiers decoding (#5584). [Bartłomiej Chmiel, Antmicro Ltd.] * Fix `rand` dynamic arrays with null handles (#5594). [Ryszard Rozak, Antmicro Ltd.] * Fix NBAs to unpacked arrays of unpacked structs (#5603). [Geza Lore] +* Fix array of struct member overwrites on member update (#5605) (#5618) (#5628). [sumpster] Verilator 5.030 2024-10-27 diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 87cd928c3..9b252f51e 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1364,7 +1364,7 @@ Summary: .. option:: --no-std Prevents parsing standard input files, alias for - :opt:`--no-std-package`, :opt:`--no-std-waiver`. This may be extended + :vlopt:`--no-std-package`, :vlopt:`--no-std-waiver`. This may be extended to prevent reading other standardized files in future versions. .. option:: --no-std-package @@ -1655,12 +1655,12 @@ Summary: .. option:: --waiver-multiline - When using :vlopt:`--waiver-output \`, include a match - expression that includes the entire multiline error message as a match - regular expression, as opposed to the default of only matching the first - line of the error message. This provides a starting point for creating - complex waivers, but such generated waivers will likely require editing - for brevity before being reused. + When using :vlopt:`--waiver-output \ <--waiver-output>`, + include a match expression that includes the entire multiline error + message as a match regular expression, as opposed to the default of only + matching the first line of the error message. This provides a starting + point for creating complex waivers, but such generated waivers will + likely require editing for brevity before being reused. .. option:: --waiver-output @@ -2111,7 +2111,7 @@ The grammar of configuration commands is as follows: the :code:`-rule`, :code:`-file`, and :code:`-contents` also match. The wildcard should be designed to match a single line; it is unspecified if the wildcard is allowed to match across multiple lines. The input - contents does not include :vlopt:`--std` standard files, nor + contents does not include :vlopt:`--std <--no-std>` standard files, nor configuration files (with :code:`verilator_config`). Typical use for this is to match a version number present in the Verilog sources, so that the waiver will only apply to that version of the sources. From f5ee7aa0ab835046afcf32caad8f5fa434e5ea84 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 24 Nov 2024 18:19:19 -0500 Subject: [PATCH 086/171] Internals: Decouple Bison class/package symbol table parsing from Link symbol table. (#5629) Not intended to change non-error cases, but side-effects are likely. --- src/V3AstNodeExpr.h | 2 + src/V3LinkDot.cpp | 80 ++++++++++++++++++++---------- src/verilog.y | 4 +- test_regress/t/t_class_mod_bad.out | 6 ++- test_regress/t/t_class_ref_bad.out | 5 +- 5 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 27a8457ac..4643a5e10 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1191,6 +1191,8 @@ class AstDot final : public AstNodeExpr { // These are eliminated in the link stage // @astgen op1 := lhsp : AstNodeExpr // @astgen op2 := rhsp : AstNodeExpr + // + // We don't have a list of elements as it's probably legal to do '(foo.bar).(baz.bap)' const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) public: AstDot(FileLine* fl, bool colon, AstNodeExpr* lhsp, AstNodeExpr* rhsp) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 722bf54f8..40aa0a413 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -765,6 +765,25 @@ public: if (!foundp) baddot = dotname; return foundp; } + VSymEnt* resolveClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool classOnly, + const string& forWhat) { + if (nodep->classOrPackagep()) return getNodeSym(nodep->classOrPackagep()); + VSymEnt* foundp = lookSymp->findIdFallback(nodep->name()); + if (!foundp && v3Global.rootp()->stdPackagep()) { // Look under implied std:: + foundp = getNodeSym(v3Global.rootp()->stdPackagep())->findIdFlat(nodep->name()); + } + if (foundp) { + nodep->classOrPackageNodep(foundp->nodep()); + return foundp; + } + const string suggest + = suggestSymFallback(lookSymp, nodep->name(), LinkNodeMatcherClassOrPackage{}); + nodep->v3error((classOnly ? "Class" : "Package/class") + << " for '" << forWhat // extends/implements + << "' not found: " << nodep->prettyNameQ() << '\n' + << (suggest.empty() ? "" : nodep->warnMore() + suggest)); + return nullptr; + } string suggestSymFallback(VSymEnt* lookupSymp, const string& name, const VNodeMatcher& matcher) { // Suggest alternative symbol in given point in hierarchy @@ -1163,6 +1182,10 @@ class LinkDotFindVisitor final : public VNVisitor { nodep->v3warn(E_UNSUPPORTED, "Unsupported: extern function definition with class-in-class"); } else { + if (!cpackagerefp->classOrPackagep()) { + m_statep->resolveClassOrPackage(m_curSymp, cpackagerefp, false, + "External definition :: reference"); + } AstClass* const classp = VN_CAST(cpackagerefp->classOrPackagep(), Class); if (!classp) { nodep->v3error("Extern declaration's scope is not a defined class"); @@ -2309,23 +2332,6 @@ class LinkDotResolveVisitor final : public VNVisitor { UASSERT_OBJ(ifaceTopVarp, nodep, "Can't find interface var ref: " << findName); return ifaceTopVarp; } - VSymEnt* findClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool classOnly, - const string& forWhat) { - if (nodep->classOrPackagep()) return m_statep->getNodeSym(nodep->classOrPackagep()); - VSymEnt* const foundp = lookSymp->findIdFallback(nodep->name()); - if (foundp) { - nodep->classOrPackageNodep(foundp->nodep()); - return foundp; - } else { - const string suggest = m_statep->suggestSymFallback(lookSymp, nodep->name(), - LinkNodeMatcherClassOrPackage{}); - nodep->v3error((classOnly ? "Class" : "Package/Class") - << " for '" << forWhat // extends/implements - << "' not found: " << nodep->prettyNameQ() << '\n' - << (suggest.empty() ? "" : nodep->warnMore() + suggest)); - return nullptr; - } - } void markAndCheckPinDup(AstPin* nodep, AstNode* refp, const char* whatp) { const auto pair = m_usedPins.emplace(refp, nodep); if (!pair.second) { @@ -2839,6 +2845,7 @@ class LinkDotResolveVisitor final : public VNVisitor { allowVar = true; allowFTask = true; staticAccess = true; + UINFO(9, "chk pkg " << m_ds.ascii() << " lhsp=" << m_ds.m_dotp->lhsp() << endl); UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), "Bad package link"); AstClassOrPackageRef* const cpackagerefp @@ -2846,6 +2853,12 @@ class LinkDotResolveVisitor final : public VNVisitor { if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; + } else if (!cpackagerefp->classOrPackagep()) { + VSymEnt* const foundp = m_statep->resolveClassOrPackage( + m_ds.m_dotSymp, cpackagerefp, false, ":: reference"); + if (!foundp) return; + classOrPackagep = cpackagerefp->classOrPackagep(); + m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); } else { classOrPackagep = cpackagerefp->classOrPackagep(); UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); @@ -3197,12 +3210,15 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep, "ClassRef has unlinked class"); UASSERT_OBJ(m_statep->forPrimary() || !nodep->paramsp(), nodep, "class reference parameter not removed by V3Param"); - { - // ClassRef's have pins, so track VL_RESTORER(m_ds); VL_RESTORER(m_pinSymp); + if (!nodep->classOrPackagep() && nodep->name() != "local::") { + m_statep->resolveClassOrPackage(m_ds.m_dotSymp, nodep, false, ":: reference"); + } + + // ClassRef's have pins, so track if (nodep->classOrPackagep()) { m_pinSymp = m_statep->getNodeSym(nodep->classOrPackagep()); } @@ -3237,6 +3253,10 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } } + if (m_ds.m_dotPos == DP_PACKAGE && nodep->classOrPackagep()) { + m_ds.m_dotSymp = m_statep->getNodeSym(nodep->classOrPackagep()); + UINFO(9, indent() << "set sym " << m_ds.ascii() << endl); + } } void visit(AstConstraintRef* nodep) override { if (nodep->user3SetOnce()) return; @@ -3485,9 +3505,11 @@ class LinkDotResolveVisitor final : public VNVisitor { if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; + } else if (!cpackagerefp->classOrPackagep()) { + VSymEnt* const foundp = m_statep->resolveClassOrPackage( + m_ds.m_dotSymp, cpackagerefp, false, ":: reference"); + if (foundp) nodep->classOrPackagep(cpackagerefp->classOrPackagep()); } else { - UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), - "Bad package link"); nodep->classOrPackagep(cpackagerefp->classOrPackagep()); } // Class/package :: HERE function() . method_called_on_function_return_value() @@ -3860,8 +3882,8 @@ class LinkDotResolveVisitor final : public VNVisitor { if (AstClassOrPackageRef* lookNodep = VN_CAST(dotp->lhsp(), ClassOrPackageRef)) { iterate(lookNodep); cprp = dotp->rhsp(); - VSymEnt* const foundp - = findClassOrPackage(lookSymp, lookNodep, false, nodep->verilogKwd()); + VSymEnt* const foundp = m_statep->resolveClassOrPackage( + lookSymp, lookNodep, false, nodep->verilogKwd()); if (!foundp) return; UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link"); lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep()); @@ -3876,8 +3898,8 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep->v3error("Attempting to extend using non-class"); // LCOV_EXCL_LINE return; } - VSymEnt* const foundp - = findClassOrPackage(lookSymp, cpackagerefp, true, nodep->verilogKwd()); + VSymEnt* const foundp = m_statep->resolveClassOrPackage(lookSymp, cpackagerefp, true, + nodep->verilogKwd()); if (foundp) { if (AstClass* const classp = VN_CAST(foundp->nodep(), Class)) { AstPin* paramsp = cpackagerefp->paramsp(); @@ -4036,10 +4058,16 @@ class LinkDotResolveVisitor final : public VNVisitor { iterate(cpackagep); return; } + if (!cpackagerefp->classOrPackagep()) { + VSymEnt* const foundp = m_statep->resolveClassOrPackage( + m_ds.m_dotSymp, cpackagerefp, false, "class/package reference"); + if (!foundp) return; + } nodep->classOrPackagep(cpackagerefp->classOrPackagep()); if (!VN_IS(nodep->classOrPackagep(), Class) && !VN_IS(nodep->classOrPackagep(), Package)) { - cpackagerefp->v3error( + // Likely impossible, as error thrown earlier + cpackagerefp->v3error( // LCOV_EXCL_LINE "'::' expected to reference a class/package but referenced '" << (nodep->classOrPackagep() ? nodep->classOrPackagep()->prettyTypeName() : "") diff --git a/src/verilog.y b/src/verilog.y index 47741bcfc..2ce3e4b08 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7295,12 +7295,12 @@ packageClassScopeItem: // IEEE: package_scope or [package_scope]::[ idCC /*mid*/ { SYMP->nextId($1); } /*cont*/ yP_COLONCOLON - { $$ = new AstClassOrPackageRef{$1, *$1, $1, nullptr}; $$ = $1; } + { $$ = new AstClassOrPackageRef{$1, *$1, nullptr, nullptr}; $$ = $1; } // | idCC parameter_value_assignmentClass /*mid*/ { SYMP->nextId($1); } // Change next *after* we handle parameters, not before /*cont*/ yP_COLONCOLON - { $$ = new AstClassOrPackageRef{$1, *$1, $1, $2}; $$ = $1; } + { $$ = new AstClassOrPackageRef{$1, *$1, nullptr, $2}; $$ = $1; } ; dollarUnitNextId: // $unit diff --git a/test_regress/t/t_class_mod_bad.out b/test_regress/t/t_class_mod_bad.out index 08ae3c20d..359343923 100644 --- a/test_regress/t/t_class_mod_bad.out +++ b/test_regress/t/t_class_mod_bad.out @@ -1,5 +1,7 @@ -%Error: t/t_class_mod_bad.v:21:7: '::' expected to reference a class/package but referenced 'MODULE 'M'' - : ... Suggest '.' instead of '::' +%Error: t/t_class_mod_bad.v:21:7: Package/class for ':: reference' not found: 'M' + 21 | M::Cls p; + | ^ +%Error: t/t_class_mod_bad.v:21:7: Package/class for 'class/package reference' not found: 'M' 21 | M::Cls p; | ^ %Error: Exiting due to diff --git a/test_regress/t/t_class_ref_bad.out b/test_regress/t/t_class_ref_bad.out index d11276ec2..e675eef7e 100644 --- a/test_regress/t/t_class_ref_bad.out +++ b/test_regress/t/t_class_ref_bad.out @@ -1,4 +1,5 @@ -%Error: Internal Error: t/t_class_ref_bad.v:15:11: ../V3LinkDot.cpp:#: Bad package link +%Error: t/t_class_ref_bad.v:15:11: Package/class for ':: reference' not found: 'ClsRigh' + : ... Suggested alternative: 'ClsRight' 15 | s = ClsRigh::m_s; | ^~~~~~~ - ... See the manual at https://verilator.org/verilator_doc.html for more assistance. +%Error: Exiting due to From f58aee2ff278d4595d6e90997c1c3d41e782d13c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 24 Nov 2024 18:33:10 -0500 Subject: [PATCH 087/171] Internals: Defer marking variables as IfaceRef until cells resolved. No functional change intended. --- src/V3AstNodeOther.h | 1 + src/V3LinkCells.cpp | 19 +++++++++++++++++++ src/verilog.y | 6 ++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 219397bac..86e2de882 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2071,6 +2071,7 @@ public: bool isPrimaryIO() const VL_MT_SAFE { return m_primaryIO; } bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } bool isIfaceRef() const { return varType() == VVarType::IFACEREF; } + void setIfaceRef() { m_varType = VVarType::IFACEREF; } bool isIfaceParent() const { return m_isIfaceParent; } bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index bd27b2f32..becf8b566 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -109,6 +109,7 @@ class LinkCellsVisitor final : public VNVisitor { // Below state needs to be preserved between each module call. AstNodeModule* m_modp = nullptr; // Current module + AstVar* m_varp = nullptr; // Current variable VSymGraph m_mods; // Symbol table of all module names LinkCellsGraph m_graph; // Linked graph of all cell interconnects LibraryVertex* m_libVertexp = nullptr; // Vertex at root of all libraries @@ -248,6 +249,9 @@ class LinkCellsVisitor final : public VNVisitor { pinp->param(true); if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); } + // Parser didn't know what was interface, resolve now + // For historical reasons virtual interface reference variables remain VARs + if (m_varp && !nodep->isVirtual()) m_varp->setIfaceRef(); // Note cannot do modport resolution here; modports are allowed underneath generates } @@ -525,6 +529,10 @@ class LinkCellsVisitor final : public VNVisitor { pinp->param(true); if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum())); } + if (m_varp) { // Parser didn't know what was interface, resolve now + const AstNodeModule* const varModp = findModuleSym(nodep->name()); + if (VN_IS(varModp, Iface)) m_varp->setIfaceRef(); + } } void visit(AstClassOrPackageRef* nodep) override { iterateChildren(nodep); @@ -538,6 +546,17 @@ class LinkCellsVisitor final : public VNVisitor { } } + void visit(AstVar* nodep) override { + { + VL_RESTORER(m_varp); + m_varp = nodep; + iterateAndNextNull(nodep->childDTypep()); + } + iterateAndNextNull(nodep->delayp()); + iterateAndNextNull(nodep->valuep()); + iterateAndNextNull(nodep->attrsp()); + } + void visit(AstNode* nodep) override { iterateChildren(nodep); } // METHODS diff --git a/src/verilog.y b/src/verilog.y index 2ce3e4b08..17c249cb3 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1528,12 +1528,14 @@ port: // ==IEEE: port // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE - { $$ = $3; VARDECL(IFACEREF); VARIO(NONE); + { // VAR for now, but V3LinkCells may call setIfcaeRef on it later + $$ = $3; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, "", *$2}; VARDTYPE(dtp); addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE - { $$ = $5; VARDECL(IFACEREF); VARIO(NONE); + { // VAR for now, but V3LinkCells may call setIfcaeRef on it later + $$ = $5; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, $4, "", *$2, *$4}; VARDTYPE(dtp); addNextNull($$, VARDONEP($$, $6, $7)); } From 6f35fec5ce2a8412d419a6d58bf3bf42655b34d8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 24 Nov 2024 20:16:54 -0500 Subject: [PATCH 088/171] Commentary --- src/V3ParseImp.cpp | 3 +-- src/verilog.y | 44 ++++++++++++++++++++++---------------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 0458a1735..0b98a6c8f 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -516,8 +516,7 @@ int V3ParseImp::tokenPipelineId(int token) { && m_tokenLastBison.token != '.') { if (const size_t depth = tokenPipeScanIdCell(0)) return yaID__aCELL; } - if (nexttok == '#') { - VL_RESTORER(yylval); // Remember value, as about to read ahead + if (nexttok == '#') { // e.g. class_type parameter_value_assignment '::' const size_t depth = tokenPipeScanParam(0, false); if (tokenPeekp(depth)->token == yP_COLONCOLON) return yaID__CC; } diff --git a/src/verilog.y b/src/verilog.y index 17c249cb3..745128bd3 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1433,7 +1433,7 @@ parameter_value_assignmentInst: // IEEE: parameter_value_assignment // // '#' delay_value { UNSUP } ; -parameter_value_assignmentClass: // IEEE: [ parameter_value_assignment ] (for classes) +parameter_value_assignmentClass: // IEEE: parameter_value_assignment (for classes) // // Like parameter_value_assignment, but for classes only, which always have #() '#' '(' cellparamListE ')' { $$ = $3; } ; @@ -1695,8 +1695,8 @@ interface_item: // IEEE: interface_item + non_port_interface_ite ; interface_or_generate_item: // ==IEEE: interface_or_generate_item - // // module_common_item in interface_item, as otherwise duplicated - // // with module_or_generate_item's module_common_item + // // module_common_item in interface_item, as otherwise duplicated + // // with module_or_generate_item's module_common_item modport_declaration { $$ = $1; } | extern_tf_declaration { $$ = $1; } ; @@ -3060,9 +3060,9 @@ assignOne: delay_or_event_controlE: // IEEE: delay_or_event_control plus empty /* empty */ { $$ = nullptr; } - | delay_control { $$ = $1; } - | event_control { $$ = $1; } - | yREPEAT '(' expr ')' event_control + | delay_control { $$ = $1; } + | event_control { $$ = $1; } + | yREPEAT '(' expr ')' event_control { $$ = $5; BBUNSUP($1, "Unsupported: repeat event control"); } ; @@ -3936,11 +3936,11 @@ range_list: // ==IEEE: range_list/open_range_list + value_range/o value_range: // ==IEEE: value_range/open_value_range expr { $$ = $1; } | '[' expr ':' expr ']' { $$ = new AstInsideRange{$1, $2, $4}; } - // // IEEE-2023: added all four: - // // Skipped as '$' is part of our expr - // // IEEE-2023: '[' '$' ':' expr ']' - // // Skipped as '$' is part of our expr - // // IEEE-2023: '[' expr ':' '$' ']' + // // IEEE-2023: added all four: + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' '$' ':' expr ']' + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' expr ':' '$' ']' | '[' expr yP_PLUSSLASHMINUS expr ']' { $$ = nullptr; BBUNSUP($1, "Unsupported: +/- range"); } | '[' expr yP_PLUSPCTMINUS expr ']' @@ -3951,11 +3951,11 @@ covergroup_value_range: // ==IEEE-2012: covergroup_value_range cgexpr { $$ = $1; } | '[' cgexpr ':' cgexpr ']' { $$ = nullptr; BBUNSUP($1, "Unsupported: covergroup value range"); } - // // IEEE-2023: added all four: - // // Skipped as '$' is part of our expr - // // IEEE-2023: '[' '$' ':' cgexpr ']' - // // Skipped as '$' is part of our expr - // // IEEE-2023: '[' cgexpr ':' '$' ']' + // // IEEE-2023: added all four: + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' '$' ':' cgexpr ']' + // // Skipped as '$' is part of our expr + // // IEEE-2023: '[' cgexpr ':' '$' ']' | '[' cgexpr yP_PLUSSLASHMINUS cgexpr ']' { $$ = nullptr; BBUNSUP($1, "Unsupported: covergroup value range"); } | '[' cgexpr yP_PLUSPCTMINUS cgexpr ']' @@ -5834,7 +5834,7 @@ variable_lvalue: // IEEE: variable_lvalue or net_lvalue | streaming_concatenation { $$ = $1; } ; -variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}' +variable_lvalueConcList: // IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}' variable_lvalue { $$ = $1; } | variable_lvalueConcList ',' variable_lvalue { $$ = new AstConcat{$2, $1, $3}; } ; @@ -6228,7 +6228,7 @@ property_port_item: // IEEE: property_port_item/sequence_port_item property_port_itemFront property_port_itemAssignment { $$ = $2; } ; -property_port_itemFront: // IEEE: part of property_port_item/sequence_port_item +property_port_itemFront: // IEEE: part of property_port_item/sequence_port_item property_port_itemDirE property_formal_typeNoDt { VARDTYPE($2); } // // data_type_or_implicit | property_port_itemDirE data_type @@ -6266,7 +6266,7 @@ property_declarationBody: // IEEE: part of property_declaration | property_spec ';' { $$ = $1; } ; -assertion_variable_declarationList: // IEEE: part of assertion_variable_declaration +assertion_variable_declarationList: // IEEE: part of assertion_variable_declaration assertion_variable_declaration { $$ = $1; } | assertion_variable_declarationList assertion_variable_declaration { $$ = addNextNull($1, $2); } @@ -6332,8 +6332,8 @@ property_spec: // IEEE: property_spec '@' '(' senitemEdge ')' yDISABLE yIFF '(' expr ')' pexpr { $$ = new AstPropSpec{$1, $3, $8, $10}; } | '@' '(' senitemEdge ')' pexpr { $$ = new AstPropSpec{$1, $3, nullptr, $5}; } - // // Disable applied after the event occurs, - // // so no existing AST can represent this + // // Disable applied after the event occurs, + // // so no existing AST can represent this | yDISABLE yIFF '(' expr ')' '@' '(' senitemEdge ')' pexpr { $$ = new AstPropSpec{$1, $8, nullptr, new AstLogOr{$1, $4, $10}}; BBUNSUP($1, "Unsupported: property '(disable iff (...) @ (...)'\n" @@ -7525,7 +7525,7 @@ dist_item: // ==IEEE: dist_item + dist_weight { $$ = new AstDistItem{$2, $1, $3}; } | value_range yP_COLONDIV expr { $$ = new AstDistItem{$2, $1, $3}; $$->isWhole(true); } - // // IEEE 1800-2023 added: + // // IEEE 1800-2023 added: | yDEFAULT yP_COLONDIV expr { BBUNSUP($2, "Unsupported: 'default :/' constraint"); $$ = nullptr; } From 1277a40b312dbe1f3dd252380c07073a71ddf6c8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 24 Nov 2024 21:12:08 -0500 Subject: [PATCH 089/171] Tests: Add driver --obj-suffix option --- test_regress/driver.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test_regress/driver.py b/test_regress/driver.py index d8a80a89a..1ae850a38 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -660,7 +660,7 @@ class VlTest: scen_dir = re.sub(r'^t/\.\./', '', scen_dir) # Not mkpath so error if try to build somewhere odd VtOs.mkdir_ok(scen_dir) - self.obj_dir = scen_dir + "/" + self.name + self.obj_dir = scen_dir + "/" + self.name + Args.obj_suffix define_opt = self._define_opt_calc() @@ -2744,6 +2744,10 @@ if __name__ == '__main__': default=0, type=int, help='parallel job count (0=cpu count)') + parser.add_argument('--obj-suffix', + action='store', + default='', + help='suffix to add to obj_ test directory name') parser.add_argument('--quiet', action='store_true', help='suppress output except failures and progress') From a934d965bebce44df4efcaa6df0cef210705ea3a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 18:25:36 -0500 Subject: [PATCH 090/171] Internals: Rename isInoutish --- src/V3Ast.h | 4 ++-- src/V3AstNodeOther.h | 3 ++- src/V3AstNodes.cpp | 6 +++--- src/V3EmitCBase.cpp | 4 ++-- src/V3EmitCImp.cpp | 2 +- src/V3Fork.cpp | 2 +- src/V3Inst.cpp | 4 ++-- src/V3SplitVar.cpp | 2 +- src/V3Task.cpp | 4 ++-- src/V3Tristate.cpp | 4 ++-- src/V3Undriven.cpp | 2 +- 11 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index 5bd63e855..4b433236a 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -786,8 +786,8 @@ public: } string prettyName() const { return verilogKwd(); } bool isAny() const { return m_e != NONE; } - // Looks like inout - "ish" because not identical to being an INOUT - bool isInoutish() const { return m_e == INOUT; } + bool isInout() const { return m_e == INOUT; } + bool isInoutOrRef() const { return m_e == INOUT || m_e == REF || m_e == CONSTREF; } bool isInput() const { return m_e == INPUT; } bool isNonOutput() const { return m_e == INPUT || m_e == INOUT || m_e == REF || m_e == CONSTREF; diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 86e2de882..9ac6180b4 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2060,7 +2060,8 @@ public: bool isAnsi() const { return m_ansi; } bool isContinuously() const { return m_isContinuously; } bool isDeclTyped() const { return m_declTyped; } - bool isInoutish() const { return m_direction.isInoutish(); } + bool isInout() const { return m_direction.isInout(); } + bool isInoutOrRef() const { return m_direction.isInoutOrRef(); } bool isInput() const { return m_direction.isInput(); } bool isNonOutput() const { return m_direction.isNonOutput(); } bool isReadOnly() const VL_MT_SAFE { return m_direction.isReadOnly(); } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index fbb5eb3de..6137f0c74 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -535,7 +535,7 @@ string AstVar::vlEnumType() const { string AstVar::vlEnumDir() const { string out; - if (isInoutish()) { + if (isInout()) { out = "VLVD_INOUT"; } else if (isWritable()) { out = "VLVD_OUT"; @@ -2448,7 +2448,7 @@ int AstVarRef::instrCount() const { void AstVar::dump(std::ostream& str) const { this->AstNode::dump(str); if (isSc()) str << " [SC]"; - if (isPrimaryIO()) str << (isInoutish() ? " [PIO]" : (isWritable() ? " [PO]" : " [PI]")); + if (isPrimaryIO()) str << (isInout() ? " [PIO]" : (isWritable() ? " [PO]" : " [PI]")); if (isIO()) str << " " << direction().ascii(); if (isConst()) str << " [CONST]"; if (isPullup()) str << " [PULLUP]"; @@ -2649,7 +2649,7 @@ bool AstNodeFTask::getPurityRecurse() const { // or any write reference to a variable that isn't an automatic function local. for (AstNode* stmtp = this->stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (const AstVar* const varp = VN_CAST(stmtp, Var)) { - if (varp->isInoutish() || varp->isRef()) return false; + if (varp->isInoutOrRef()) return false; } if (!stmtp->isPure()) return false; if (stmtp->exists([](const AstNodeVarRef* const varrefp) { diff --git a/src/V3EmitCBase.cpp b/src/V3EmitCBase.cpp index 7f9d33cea..15177d6ec 100644 --- a/src/V3EmitCBase.cpp +++ b/src/V3EmitCBase.cpp @@ -192,7 +192,7 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) { if (nodep->attrScClocked() && nodep->isReadOnly()) { putns(nodep, "sc_core::sc_in_clk "); } else { - if (nodep->isInoutish()) { + if (nodep->isInout()) { putns(nodep, "sc_core::sc_inout<"); } else if (nodep->isWritable()) { putns(nodep, "sc_core::sc_out<"); @@ -213,7 +213,7 @@ void EmitCBaseVisitorConst::emitVarDecl(const AstVar* nodep, bool asRef) { emitDeclArrayBrackets(nodep); puts(";\n"); } else if (nodep->isIO() && basicp && !basicp->isOpaque()) { - if (nodep->isInoutish()) { + if (nodep->isInout()) { putns(nodep, "VL_INOUT"); } else if (nodep->isWritable()) { putns(nodep, "VL_OUT"); diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index 5df77cf92..544c82d7c 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -733,7 +733,7 @@ class EmitCTrace final : EmitCFunc { puts("," + cvtToStr(enumNum)); // Direction - if (nodep->declDirection().isInoutish()) { + if (nodep->declDirection().isInout()) { puts(", VerilatedTraceSigDirection::INOUT"); } else if (nodep->declDirection().isWritable()) { puts(", VerilatedTraceSigDirection::OUTPUT"); diff --git a/src/V3Fork.cpp b/src/V3Fork.cpp index aa9aafff4..30dc0fa82 100644 --- a/src/V3Fork.cpp +++ b/src/V3Fork.cpp @@ -433,7 +433,7 @@ class DynScopeVisitor final : public VNVisitor { nodep->v3warn( E_UNSUPPORTED, "Unsupported: Writing to a captured " - << (nodep->varp()->isInoutish() ? "inout" : "output") << " variable in a " + << (nodep->varp()->isInout() ? "inout" : "output") << " variable in a " << (VN_IS(nodep->backp(), AssignDly) ? "non-blocking assignment" : "fork") << " after a timing control"); } diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index d8c810180..0d69913aa 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -67,7 +67,7 @@ class InstVisitor final : public VNVisitor { AstNodeExpr* const exprp = VN_AS(nodep->exprp(), NodeExpr)->cloneTree(false); UASSERT_OBJ(exprp->width() == nodep->modVarp()->width(), nodep, "Width mismatch, should have been handled in pinReconnectSimple"); - if (nodep->modVarp()->isInoutish()) { + if (nodep->modVarp()->isInout()) { nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator"); } else if (nodep->modVarp()->isWritable()) { AstNodeExpr* const rhsp = new AstVarXRef{exprp->fileline(), nodep->modVarp(), @@ -558,7 +558,7 @@ public: // Important to add statement next to cell, in case there is a // generate with same named cell cellp->addNextHere(newvarp); - if (pinVarp->isInoutish()) { + if (pinVarp->isInout()) { pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be" " direct one-to-one connection (without any expression)"); } else if (pinVarp->isWritable()) { diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index 23847a076..b09a7a95b 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -775,7 +775,7 @@ public: const std::pair dim = nodep->dtypep()->dimensions(false); UINFO(7, nodep->prettyNameQ() << " pub:" << nodep->isSigPublic() << " pri:" << nodep->isPrimaryIO() - << " io:" << nodep->isInoutish() << " typ:" << nodep->varType() << "\n"); + << " io:" << nodep->isInout() << " typ:" << nodep->varType() << "\n"); const char* reason = nullptr; // Public variable cannot be split. // at least one unpacked dimension must exist diff --git a/src/V3Task.cpp b/src/V3Task.cpp index b2603a1cd..f7b810765 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -515,7 +515,7 @@ class TaskVisitor final : public VNVisitor { pinp->v3fatalSrc("ref argument should have caused non-inline of function"); } } - } else if (portp->isInoutish()) { + } else if (portp->isInout()) { // if (debug() >= 9) pinp->dumpTree("-pinrsize- "); AstVarScope* const newvscp @@ -900,7 +900,7 @@ class TaskVisitor final : public VNVisitor { if (portp->isNonOutput()) { std::string frName - = portp->isInoutish() && portp->basicp()->isDpiPrimitive() + = portp->isInout() && portp->basicp()->isDpiPrimitive() && portp->dtypep()->skipRefp()->arrayUnpackedElements() == 1 ? "*" : ""; diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 6663c879e..c47eea9a5 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -23,7 +23,7 @@ // Over each module, from child to parent: // Build a graph, connecting signals together so we can propagate tristates // Variable becomes tristate with -// VAR->isInoutish +// VAR->isInout // VAR->isPullup/isPulldown (converted to AstPullup/AstPulldown // BufIf0/1 // All variables on the LHS need to become tristate when there is: @@ -1779,7 +1779,7 @@ class TristateVisitor final : public TristateBaseVisitor { nodep->addNextHere(newp); // We'll iterate on the new AstPull later } - if (nodep->isInoutish() + if (nodep->isInout() //|| varp->isOutput() // Note unconnected output only changes behavior vs. previous // versions and causes outputs that don't come from anywhere to diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 0c518ebcd..1794d06da 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -504,7 +504,7 @@ class UndrivenVisitor final : public VNVisitorConst { } void visit(AstPin* nodep) override { VL_RESTORER(m_inInoutPin); - m_inInoutPin = nodep->modVarp()->isInoutish(); + m_inInoutPin = nodep->modVarp()->isInout(); iterateChildrenConst(nodep); } From a72009fb41961d3f7497cbd448b671c9eed2fff0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 18:41:38 -0500 Subject: [PATCH 091/171] Fix UNDRIVEN on refs --- src/V3Undriven.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 1794d06da..483541b39 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -279,7 +279,7 @@ class UndrivenVisitor final : public VNVisitorConst { bool m_inContAssign = false; // In continuous assignment bool m_inProcAssign = false; // In procedural assignment bool m_inFTaskRef = false; // In function or task call - bool m_inInoutPin = false; // Connected to pin that is inout + bool m_inInoutOrRefPin = false; // Connected to pin that is inout const AstNodeFTask* m_taskp = nullptr; // Current task const AstAlways* m_alwaysCombp = nullptr; // Current always if combo, otherwise nullptr @@ -452,7 +452,7 @@ class UndrivenVisitor final : public VNVisitorConst { // Inouts have only isWrite set, as we don't have more // information and operating on module boundary, treat as // both read and writing - || m_inInoutPin) + || m_inInoutOrRefPin) entryp->usedWhole(); } } @@ -503,8 +503,8 @@ class UndrivenVisitor final : public VNVisitorConst { iterateChildrenConst(nodep); } void visit(AstPin* nodep) override { - VL_RESTORER(m_inInoutPin); - m_inInoutPin = nodep->modVarp()->isInout(); + VL_RESTORER(m_inInoutOrRefPin); + m_inInoutOrRefPin = nodep->modVarp()->isInoutOrRef(); iterateChildrenConst(nodep); } From 25d75ee86f91dc20e305f40b7e0d724ab41f3238 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 19:59:10 -0500 Subject: [PATCH 092/171] Add `--fno-inline-funcs` to disable function inlining. --- Changes | 1 + docs/guide/exe_verilator.rst | 2 ++ src/V3Options.cpp | 1 + src/V3Options.h | 2 ++ src/V3Task.cpp | 11 +++++++++-- test_regress/driver.py | 4 ++-- test_regress/t/t_opt_inline_funcs.py | 18 ++++++++++++++++++ test_regress/t/t_opt_inline_funcs.v | 21 +++++++++++++++++++++ test_regress/t/t_opt_inline_funcs_no.py | 19 +++++++++++++++++++ 9 files changed, 75 insertions(+), 4 deletions(-) create mode 100755 test_regress/t/t_opt_inline_funcs.py create mode 100644 test_regress/t/t_opt_inline_funcs.v create mode 100755 test_regress/t/t_opt_inline_funcs_no.py diff --git a/Changes b/Changes index 35974cbf0..a429b4e0e 100644 --- a/Changes +++ b/Changes @@ -29,6 +29,7 @@ Verilator 5.031 devel * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add error on `solve before` or soft constraints of `randc` variable. +* Add `--fno-inline-funcs` to disable function inlining. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). * Fix `function fork...join_none` regression with unknown type (#4449). diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 9b252f51e..5b9aaf3f0 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -599,6 +599,8 @@ Summary: .. option:: -fno-inline +.. option:: -fno-inline-funcs + .. option:: -fno-life .. option:: -fno-life-post diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 2980e3467..a5ea5f7e0 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1317,6 +1317,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-ffunc-opt-split-cat", FOnOff, &m_fFuncSplitCat); DECL_OPTION("-fgate", FOnOff, &m_fGate); DECL_OPTION("-finline", FOnOff, &m_fInline); + DECL_OPTION("-finline-funcs", FOnOff, &m_fInlineFuncs); DECL_OPTION("-flife", FOnOff, &m_fLife); DECL_OPTION("-flife-post", FOnOff, &m_fLifePost); DECL_OPTION("-flocalize", FOnOff, &m_fLocalize); diff --git a/src/V3Options.h b/src/V3Options.h index c1b295c90..c60a86224 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -390,6 +390,7 @@ private: bool m_fFuncSplitCat = true; // main switch: -fno-func-split-cat: expansion of C macros bool m_fGate; // main switch: -fno-gate: gate wire elimination bool m_fInline; // main switch: -fno-inline: module inlining + bool m_fInlineFuncs = true; // main switch: -fno-inline-funcs: function inlining bool m_fLife; // main switch: -fno-life: variable lifetime bool m_fLifePost; // main switch: -fno-life-post: delayed assignment elimination bool m_fLocalize; // main switch: -fno-localize: convert temps to local variables @@ -685,6 +686,7 @@ public: bool fFunc() const { return fFuncSplitCat() || fFuncBalanceCat(); } bool fGate() const { return m_fGate; } bool fInline() const { return m_fInline; } + bool fInlineFuncs() const { return m_fInlineFuncs; } bool fLife() const { return m_fLife; } bool fLifePost() const { return m_fLifePost; } bool fLocalize() const { return m_fLocalize; } diff --git a/src/V3Task.cpp b/src/V3Task.cpp index f7b810765..b54af15c1 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -30,6 +30,7 @@ #include "V3Const.h" #include "V3EmitCBase.h" #include "V3Graph.h" +#include "V3Stats.h" #include @@ -132,7 +133,9 @@ public: void remapFuncClassp(AstNodeFTask* nodep, AstNodeFTask* newp) { m_funcToClassMap[newp] = getClassp(nodep); } - bool ftaskNoInline(AstNodeFTask* nodep) { return getFTaskVertex(nodep)->noInline(); } + bool ftaskNoInline(AstNodeFTask* nodep) { + return !v3Global.opt.fInlineFuncs() || getFTaskVertex(nodep)->noInline(); + } AstCFunc* ftaskCFuncp(AstNodeFTask* nodep) { return getFTaskVertex(nodep)->cFuncp(); } void ftaskCFuncp(AstNodeFTask* nodep, AstCFunc* cfuncp) { getFTaskVertex(nodep)->cFuncp(cfuncp); @@ -365,7 +368,10 @@ class TaskVisitor final : public VNVisitor { AstNode* m_insStmtp = nullptr; // Where to insert statement bool m_inSensesp = false; // Are we under a senitem? int m_modNCalls = 0; // Incrementing func # for making symbols + + // STATE - across all visitors DpiCFuncs m_dpiNames; // Map of all created DPI functions + VDouble0 m_statInlines; // Statistic tracking // METHODS @@ -1454,6 +1460,7 @@ class TaskVisitor final : public VNVisitor { beginp = createNonInlinedFTask(nodep, namePrefix, outvscp, cnewp /*ref*/); } else { beginp = createInlinedFTask(nodep, namePrefix, outvscp); + ++m_statInlines; } if (VN_IS(nodep, New)) { @@ -1606,7 +1613,7 @@ public: : m_statep{statep} { iterate(nodep); } - ~TaskVisitor() override = default; + ~TaskVisitor() { V3Stats::addStat("Optimizations, Functions inlined", m_statInlines); } }; //###################################################################### diff --git a/test_regress/driver.py b/test_regress/driver.py index 1ae850a38..cd7015d23 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -2450,7 +2450,7 @@ class VlTest: if not match: self.error("File_grep: " + filename + ": Regexp not found: " + regexp) return None - if expvalue and str(expvalue) != match.group(1): + if expvalue is not None and str(expvalue) != match.group(1): self.error("File_grep: " + filename + ": Got='" + match.group(1) + "' Expected='" + str(expvalue) + "' in regexp: '" + regexp + "'") return None @@ -2472,7 +2472,7 @@ class VlTest: return match = re.search(regexp, contents) if match: - if expvalue and str(expvalue) != match.group(1): + if expvalue is not None and str(expvalue) != match.group(1): self.error("file_grep: " + filename + ": Got='" + match.group(1) + "' Expected='" + str(expvalue) + "' in regexp: " + regexp) return diff --git a/test_regress/t/t_opt_inline_funcs.py b/test_regress/t/t_opt_inline_funcs.py new file mode 100755 index 000000000..53c9b79fa --- /dev/null +++ b/test_regress/t/t_opt_inline_funcs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.compile(verilator_flags2=['--stats'], verilator_make_gmake=False) + +test.file_grep(test.stats, r'Optimizations, Functions inlined\s+(\d+)', 2) + +test.passes() diff --git a/test_regress/t/t_opt_inline_funcs.v b/test_regress/t/t_opt_inline_funcs.v new file mode 100644 index 000000000..0fb2c6e2b --- /dev/null +++ b/test_regress/t/t_opt_inline_funcs.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + function void allfin; + $write("*-* All Finished *-*\n"); + endfunction + + task done; + $finish; + endtask + + initial begin + allfin(); + done(); + end +endmodule diff --git a/test_regress/t/t_opt_inline_funcs_no.py b/test_regress/t/t_opt_inline_funcs_no.py new file mode 100755 index 000000000..28f5acd13 --- /dev/null +++ b/test_regress/t/t_opt_inline_funcs_no.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t/t_opt_inline_funcs.v" + +test.compile(verilator_flags2=['--fno-inline-funcs', '--stats'], verilator_make_gmake=False) + +test.file_grep(test.stats, r'Optimizations, Functions inlined\s+(\d+)', 0) + +test.passes() From 2ba0749993e5010372777c014d642ab01e06e4da Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 20:38:41 -0500 Subject: [PATCH 093/171] Tests: Verify function ref (#3385) --- test_regress/t/t_func_ref.v | 19 +++++++++++++++++++ test_regress/t/t_func_ref_noinline.py | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100755 test_regress/t/t_func_ref_noinline.py diff --git a/test_regress/t/t_func_ref.v b/test_regress/t/t_func_ref.v index b650ecf2b..1559a5d82 100644 --- a/test_regress/t/t_func_ref.v +++ b/test_regress/t/t_func_ref.v @@ -24,6 +24,16 @@ module t (/*AUTOARG*/); int b; int arr[1]; MyInt mi; + + task update_inout(inout int flag, input bit upflag); + flag = upflag ? 1 + flag : flag; + endtask + task update_ref(ref int flag, input bit upflag); + flag = upflag ? 1 + flag : flag; + endtask + + int my_flag; + initial begin mi = new(1); b = get_val_set_5(mi.x); @@ -35,6 +45,15 @@ module t (/*AUTOARG*/); `checkh(arr[0], 5); `checkh(b, 10); + update_ref(my_flag, 1); + if (my_flag !== 1) $stop; + update_ref(my_flag, 0); + if (my_flag !== 1) $stop; + update_inout(my_flag, 1); + if (my_flag !== 2) $stop; + update_inout(my_flag, 0); + if (my_flag !== 2) $stop; + $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_func_ref_noinline.py b/test_regress/t/t_func_ref_noinline.py new file mode 100755 index 000000000..475f46f55 --- /dev/null +++ b/test_regress/t/t_func_ref_noinline.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = "t/t_func_ref.v" + +test.compile() + +test.execute() + +test.passes() From 7a9140821d39114331c922e8f453f182207abd45 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 21:21:11 -0500 Subject: [PATCH 094/171] Fix public_module requiring a wire to become public (#4916). --- Changes | 1 + src/V3Dead.cpp | 20 ++++++++++---------- test_regress/t/t_inst_public.py | 19 +++++++++++++++++++ test_regress/t/t_inst_public.v | 31 +++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100755 test_regress/t/t_inst_public.py create mode 100644 test_regress/t/t_inst_public.v diff --git a/Changes b/Changes index a429b4e0e..1e028eac2 100644 --- a/Changes +++ b/Changes @@ -33,6 +33,7 @@ Verilator 5.031 devel * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). * Fix `function fork...join_none` regression with unknown type (#4449). +* Fix public_module requiring a wire to become public (#4916). [Andrew Nolte] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index a957da964..a0303ccfb 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -109,16 +109,16 @@ class DeadVisitor final : public VNVisitor { if (m_modp) m_modp->user1Inc(); // e.g. Class under Package VL_RESTORER(m_modp); m_modp = nodep; - if (!nodep->dead()) { - iterateChildren(nodep); - checkAll(nodep); - if (AstClass* const classp = VN_CAST(nodep, Class)) { - if (classp->extendsp()) classp->extendsp()->user1Inc(); - if (classp->classOrPackagep()) classp->classOrPackagep()->user1Inc(); - m_classesp.push_back(classp); - // TODO we don't reclaim dead classes yet - graph implementation instead? - classp->user1Inc(); - } + if (nodep->dead()) return; + if (nodep->modPublic()) m_modp->user1Inc(); + iterateChildren(nodep); + checkAll(nodep); + if (AstClass* const classp = VN_CAST(nodep, Class)) { + if (classp->extendsp()) classp->extendsp()->user1Inc(); + if (classp->classOrPackagep()) classp->classOrPackagep()->user1Inc(); + m_classesp.push_back(classp); + // TODO we don't reclaim dead classes yet - graph implementation instead? + classp->user1Inc(); } } void visit(AstCFunc* nodep) override { diff --git a/test_regress/t/t_inst_public.py b/test_regress/t/t_inst_public.py new file mode 100755 index 000000000..c4062aa79 --- /dev/null +++ b/test_regress/t/t_inst_public.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_make_gmake=False) + +test.file_grep(test.obj_dir + "/" + test.vm_prefix + "_Pub.h", r'') +test.file_grep_not(test.obj_dir + "/" + test.vm_prefix + "__Syms.h", r'Dead') + +test.passes() diff --git a/test_regress/t/t_inst_public.v b/test_regress/t/t_inst_public.v new file mode 100644 index 000000000..4b30fab8f --- /dev/null +++ b/test_regress/t/t_inst_public.v @@ -0,0 +1,31 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + Pub pub(); + + localparam ZERO = 0; + if (ZERO) Dead dead(); + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + +module Pub; + + // verilator public_module + + // no signals here + +endmodule + +module Dead; + // verilator public_module +endmodule From 29ad93c89da4c29bc4466754058e2f10692ea789 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 25 Nov 2024 21:50:24 -0500 Subject: [PATCH 095/171] Tests: Add t_interface_colon_bad (#5281) --- test_regress/t/t_interface_colon_bad.out | 7 +++++++ test_regress/t/t_interface_colon_bad.py | 16 ++++++++++++++++ test_regress/t/t_interface_colon_bad.v | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 test_regress/t/t_interface_colon_bad.out create mode 100755 test_regress/t/t_interface_colon_bad.py create mode 100644 test_regress/t/t_interface_colon_bad.v diff --git a/test_regress/t/t_interface_colon_bad.out b/test_regress/t/t_interface_colon_bad.out new file mode 100644 index 000000000..f19261595 --- /dev/null +++ b/test_regress/t/t_interface_colon_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_interface_colon_bad.v:14:7: Package/class for ':: reference' not found: 'iface' + 14 | iface::func(); + | ^~~~~ +%Error: t/t_interface_colon_bad.v:14:14: Can't find definition of task/function: 'func' + 14 | iface::func(); + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_interface_colon_bad.py b/test_regress/t/t_interface_colon_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_interface_colon_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_interface_colon_bad.v b/test_regress/t/t_interface_colon_bad.v new file mode 100644 index 000000000..904468bca --- /dev/null +++ b/test_regress/t/t_interface_colon_bad.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface iface; + function static func; + endfunction +endinterface + +module t; + initial begin + iface::func(); // BAD + $stop; + end +endmodule From 713dab278c201b68db658087ff6cafde0671ee8d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 26 Nov 2024 19:16:05 -0500 Subject: [PATCH 096/171] Fix mis-public interfaces, broke in f58aee2ff278d4595d6e90997c1c3d41e782d13c --- src/V3LinkParse.cpp | 13 ++++++----- test_regress/t/t_interface_notpublic.py | 18 +++++++++++++++ test_regress/t/t_interface_notpublic.v | 29 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 5 deletions(-) create mode 100755 test_regress/t/t_interface_notpublic.py create mode 100644 test_regress/t/t_interface_notpublic.v diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 1a8956a43..5c1ece2ae 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -430,20 +430,23 @@ class LinkParseVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - m_varp->sigUserRWPublic(true); - m_varp->sigModPublic(true); + // Public ifacerefs aren't supported - be compatible with older parser that ignored it + if (!m_varp->isIfaceRef()) { + m_varp->sigUserRWPublic(true); + m_varp->sigModPublic(true); + } VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - m_varp->sigUserRWPublic(true); + if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RD) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - m_varp->sigUserRdPublic(true); + if (!m_varp->isIfaceRef()) m_varp->sigUserRdPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RW) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - m_varp->sigUserRWPublic(true); + if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_ISOLATE_ASSIGNMENTS) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); diff --git a/test_regress/t/t_interface_notpublic.py b/test_regress/t/t_interface_notpublic.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_notpublic.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_notpublic.v b/test_regress/t/t_interface_notpublic.v new file mode 100644 index 000000000..7619519e8 --- /dev/null +++ b/test_regress/t/t_interface_notpublic.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Iztok Jeras. +// SPDX-License-Identifier: CC0-1.0 + +interface intf + (input wire clk, + input wire rst); + modport intf_modp (input clk, rst); +endinterface + +module sub + // verilator public_on + (intf.intf_modp intf_port); + + always @ (posedge intf_port.clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end + // verilator public_off +endmodule + +module t(clk); + input clk /*verilator public*/ ; + logic rst; + intf the_intf (.clk, .rst); + sub the_sub (.intf_port (the_intf)); +endmodule From bee344d1aec2939dfe4bb9151169740eba016b92 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 26 Nov 2024 21:06:43 -0500 Subject: [PATCH 097/171] Add error on illegal `--prefix` etc. values (#5507). --- Changes | 1 + src/V3Options.cpp | 24 ++++++++++++++++++++---- src/V3Options.h | 1 + src/V3PreProc.cpp | 2 +- src/V3String.cpp | 11 +++++++++-- src/V3String.h | 6 ++++-- test_regress/t/t_flag_libcreate_bad.out | 2 ++ test_regress/t/t_flag_libcreate_bad.py | 19 +++++++++++++++++++ test_regress/t/t_flag_modprefix_bad.out | 2 ++ test_regress/t/t_flag_modprefix_bad.py | 19 +++++++++++++++++++ test_regress/t/t_flag_prefix_bad.out | 2 ++ test_regress/t/t_flag_prefix_bad.py | 17 +++++++++++++++++ 12 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 test_regress/t/t_flag_libcreate_bad.out create mode 100755 test_regress/t/t_flag_libcreate_bad.py create mode 100644 test_regress/t/t_flag_modprefix_bad.out create mode 100755 test_regress/t/t_flag_modprefix_bad.py create mode 100644 test_regress/t/t_flag_prefix_bad.out create mode 100755 test_regress/t/t_flag_prefix_bad.py diff --git a/Changes b/Changes index 1e028eac2..bd47bdfd3 100644 --- a/Changes +++ b/Changes @@ -26,6 +26,7 @@ Verilator 5.031 devel * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] +* Add error on illegal `--prefix` etc. values (#5507). [Fabian Keßler] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add error on `solve before` or soft constraints of `randc` variable. diff --git a/src/V3Options.cpp b/src/V3Options.cpp index a5ea5f7e0..01b57af48 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -561,6 +561,12 @@ int V3Options::stripOptionsForChildRun(const string& opt, bool forTop) { return 0; } +void V3Options::validateIdentifier(FileLine* fl, const string& arg, const string& opt) { + if (!VString::isIdentifier(arg)) { + fl->v3error(opt << " argument must be a legal C++ identifier: '" << arg << "'"); + } +} + string V3Options::filePath(FileLine* fl, const string& modname, const string& lastpath, const string& errmsg) { // Error prefix or "" to suppress error // Find a filename to read the specified module name, @@ -1386,7 +1392,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, }; DECL_OPTION("-default-language", CbVal, setLang); DECL_OPTION("-language", CbVal, setLang); - DECL_OPTION("-lib-create", Set, &m_libCreate); + DECL_OPTION("-lib-create", CbVal, [this, fl](const char* valp) { + validateIdentifier(fl, valp, "--lib-create"); + m_libCreate = valp; + }); DECL_OPTION("-lint-only", OnOff, &m_lintOnly); DECL_OPTION("-localize-max-size", Set, &m_localizeMaxSize); DECL_OPTION("-main-top-name", Set, &m_mainTopName); @@ -1409,7 +1418,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, } }); DECL_OPTION("-max-num-width", Set, &m_maxNumWidth); - DECL_OPTION("-mod-prefix", Set, &m_modPrefix); + DECL_OPTION("-mod-prefix", CbVal, [this, fl](const char* valp) { + validateIdentifier(fl, valp, "--mod-prefix"); + m_modPrefix = valp; + }); DECL_OPTION("-O0", CbCall, [this]() { optimize(0); }); DECL_OPTION("-O1", CbCall, [this]() { optimize(1); }); @@ -1460,7 +1472,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-pins-uint8", OnOff, &m_pinsUint8); DECL_OPTION("-pipe-filter", Set, &m_pipeFilter); DECL_OPTION("-pp-comments", OnOff, &m_ppComments); - DECL_OPTION("-prefix", Set, &m_prefix); + DECL_OPTION("-prefix", CbVal, [this, fl](const char* valp) { + validateIdentifier(fl, valp, "--prefix"); + m_prefix = valp; + }); DECL_OPTION("-private", CbCall, [this]() { m_public = false; }); DECL_OPTION("-prof-c", OnOff, &m_profC); DECL_OPTION("-prof-cfuncs", CbCall, [this]() { m_profC = m_profCFuncs = true; }); @@ -1470,7 +1485,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-prof-pgo", OnOff, &m_profPgo); DECL_OPTION("-protect-ids", OnOff, &m_protectIds); DECL_OPTION("-protect-key", Set, &m_protectKey); - DECL_OPTION("-protect-lib", CbVal, [this](const char* valp) { + DECL_OPTION("-protect-lib", CbVal, [this, fl](const char* valp) { + validateIdentifier(fl, valp, "--protect-lib"); m_libCreate = valp; m_protectIds = true; }); diff --git a/src/V3Options.h b/src/V3Options.h index c60a86224..f7a05a022 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -428,6 +428,7 @@ private: static string parseFileArg(const string& optdir, const string& relfilename); string filePathCheckOneDir(const string& modname, const string& dirname); static int stripOptionsForChildRun(const string& opt, bool forTop); + void validateIdentifier(FileLine* fl, const string& arg, const string& opt); // CONSTRUCTORS VL_UNCOPYABLE(V3Options); diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 6cb95aa28..c2cb514b3 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -490,7 +490,7 @@ void V3PreProcImp::comment(const string& text) { if (VString::startsWith(cmd, "public_flat_rw")) { // "/*verilator public_flat_rw @(foo) */" -> "/*verilator public_flat_rw*/ @(foo)" string::size_type endOfCmd = std::strlen("public_flat_rw"); - while (VString::isWordChar(cmd[endOfCmd])) ++endOfCmd; + while (VString::isIdentifierChar(cmd[endOfCmd])) ++endOfCmd; string baseCmd = cmd.substr(0, endOfCmd); string arg = cmd.substr(endOfCmd); while (std::isspace(arg[0])) arg = arg.substr(1); diff --git a/src/V3String.cpp b/src/V3String.cpp index d79a6ff58..c0f8f036d 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -216,6 +216,13 @@ string VString::removeWhitespace(const string& str) { return result; } +bool VString::isIdentifier(const string& str) { + for (const char c : str) { + if (!isIdentifierChar(c)) return false; + } + return true; +} + bool VString::isWhitespace(const string& str) { for (const char c : str) { if (!std::isspace(c)) return false; @@ -256,8 +263,8 @@ string VString::replaceWord(const string& str, const string& from, const string& UASSERT_STATIC(len > 0, "Cannot replace empty string"); for (size_t pos = 0; (pos = result.find(from, pos)) != string::npos; pos += len) { // Only replace whole words - if (((pos > 0) && VString::isWordChar(result[pos - 1])) || // - ((pos + len < result.size()) && VString::isWordChar(result[pos + len]))) { + if (((pos > 0) && VString::isIdentifierChar(result[pos - 1])) || // + ((pos + len < result.size()) && VString::isIdentifierChar(result[pos + len]))) { continue; } result.replace(pos, len, to); diff --git a/src/V3String.h b/src/V3String.h index a69036cc9..83db7eed9 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -114,6 +114,10 @@ public: static string spaceUnprintable(const string& str) VL_PURE; // Remove any whitespace static string removeWhitespace(const string& str); + // Return true if only identifer or "" + static bool isIdentifier(const string& str); + // Return true if char is valid character in C identifiers + static bool isIdentifierChar(char c) { return isalnum(c) || c == '_'; } // Return true if only whitespace or "" static bool isWhitespace(const string& str); // Return number of spaces/tabs leading in string @@ -128,8 +132,6 @@ public: static bool startsWith(const string& str, const string& prefix); // Predicate to check if 'str' ends with 'suffix' static bool endsWith(const string& str, const string& suffix); - // Return true if char is valid character in word - static bool isWordChar(char c) { return isalnum(c) || c == '_'; } // Return proper article (a/an) for a word. May be inaccurate for some special words static string aOrAn(const char* word); static string aOrAn(const string& word) { return aOrAn(word.c_str()); } diff --git a/test_regress/t/t_flag_libcreate_bad.out b/test_regress/t/t_flag_libcreate_bad.out new file mode 100644 index 000000000..c4912f7c5 --- /dev/null +++ b/test_regress/t/t_flag_libcreate_bad.out @@ -0,0 +1,2 @@ +%Error: --lib-create argument must be a legal C++ identifier: 'bad/name' +%Error: Exiting due to diff --git a/test_regress/t/t_flag_libcreate_bad.py b/test_regress/t/t_flag_libcreate_bad.py new file mode 100755 index 000000000..8923eb5f0 --- /dev/null +++ b/test_regress/t/t_flag_libcreate_bad.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = 't/t_EXAMPLE.v' # Anything + +test.lint(verilator_flags2=["--lib-create bad/name"], + fails=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_modprefix_bad.out b/test_regress/t/t_flag_modprefix_bad.out new file mode 100644 index 000000000..e20cabf72 --- /dev/null +++ b/test_regress/t/t_flag_modprefix_bad.out @@ -0,0 +1,2 @@ +%Error: --mod-prefix argument must be a legal C++ identifier: 'bad/name' +%Error: Exiting due to diff --git a/test_regress/t/t_flag_modprefix_bad.py b/test_regress/t/t_flag_modprefix_bad.py new file mode 100755 index 000000000..7d78e05da --- /dev/null +++ b/test_regress/t/t_flag_modprefix_bad.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = 't/t_EXAMPLE.v' # Anything + +test.lint(verilator_flags2=["--mod-prefix bad/name"], + fails=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_flag_prefix_bad.out b/test_regress/t/t_flag_prefix_bad.out new file mode 100644 index 000000000..d87a75861 --- /dev/null +++ b/test_regress/t/t_flag_prefix_bad.out @@ -0,0 +1,2 @@ +%Error: --prefix argument must be a legal C++ identifier: 'bad/name' +%Error: Exiting due to diff --git a/test_regress/t/t_flag_prefix_bad.py b/test_regress/t/t_flag_prefix_bad.py new file mode 100755 index 000000000..70b21989f --- /dev/null +++ b/test_regress/t/t_flag_prefix_bad.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = 't/t_EXAMPLE.v' # Anything + +test.lint(verilator_flags2=["--prefix bad/name"], fails=True, expect_filename=test.golden_filename) + +test.passes() From e14903cfb23fccaeec99137168075774c40bdf75 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 26 Nov 2024 22:10:54 -0500 Subject: [PATCH 098/171] Internals: Fix null skipRef for consistency. No functional change intended. --- src/V3AstNodeDType.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 2e0c658d5..4c0aeae79 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -1069,7 +1069,7 @@ public: // METHODS bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return nullptr; } + AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } // cppcheck-suppress csyleCast AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } // cppcheck-suppress csyleCast From 99daa8d24b0b9295448b53657108ec3d5cd7f25e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 26 Nov 2024 22:27:32 -0500 Subject: [PATCH 099/171] Support `default disable iff` and `$inferred_disable` (#4016). --- Changes | 1 + src/V3AssertPre.cpp | 30 +++++++++- src/V3AstNodeExpr.h | 12 ++++ src/V3AstNodeOther.h | 10 ++++ src/V3Width.cpp | 8 +++ src/verilog.l | 1 + src/verilog.y | 12 +++- test_regress/t/t_EXAMPLE.v | 8 ++- test_regress/t/t_assert_disable_bad.v | 6 +- test_regress/t/t_assert_disable_count.py | 18 ++++++ test_regress/t/t_assert_disable_count.v | 69 ++++++++++++++++++++++ test_regress/t/t_assert_disable_iff.v | 62 ++++++------------- test_regress/t/t_disable_iff_multi_bad.out | 7 +-- 13 files changed, 185 insertions(+), 59 deletions(-) create mode 100755 test_regress/t/t_assert_disable_count.py create mode 100644 test_regress/t/t_assert_disable_count.v diff --git a/Changes b/Changes index bd47bdfd3..c650faff4 100644 --- a/Changes +++ b/Changes @@ -18,6 +18,7 @@ Verilator 5.031 devel * Support vpiDefName (#3906) (#5572). [Krzysztof Starecki] * Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill] * Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.] +* Support `default disable iff` and `$inferred_disable` (#4016). [Srinivasan Venkataramanan] * Support `pure constraint`. * Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). * Add `--no-std-package` as subset-alias of `--no-std` (#5607). diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index d22004656..df9fbbe07 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -45,7 +45,8 @@ private: AstNodeModule* m_modp = nullptr; // Current module AstClocking* m_clockingp = nullptr; // Current clocking block // Reset each module: - AstClocking* m_defaultClockingp = nullptr; // Default clocking for the current module + AstClocking* m_defaultClockingp = nullptr; // Default clocking for current module + AstDefaultDisable* m_defaultDisablep = nullptr; // Default disable for current module // Reset each assertion: AstSenItem* m_senip = nullptr; // Last sensitivity // Reset each always: @@ -522,6 +523,21 @@ private: VL_DO_DANGLING(pushDeletep(nodep), nodep); } + void visit(AstDefaultDisable* nodep) override { + // Done with these + VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep); + } + void visit(AstInferredDisable* nodep) override { + AstNode* newp; + if (m_defaultDisablep) { + newp = m_defaultDisablep->condp()->cloneTreePure(true); + } else { + newp = new AstConst{nodep->fileline(), AstConst::BitFalse{}}; + } + nodep->replaceWith(newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } + void visit(AstPropSpec* nodep) override { nodep = substitutePropertyCall(nodep); // No need to iterate the body, once replace will get iterated @@ -530,6 +546,9 @@ private: nodep->v3warn(E_UNSUPPORTED, "Unsupported: Only one PSL clock allowed per assertion"); // Block is the new expression to evaluate AstNodeExpr* blockp = VN_AS(nodep->propp()->unlinkFrBack(), NodeExpr); + if (!nodep->disablep() && m_defaultDisablep) { + nodep->disablep(m_defaultDisablep->condp()->cloneTreePure(true)); + } if (AstNodeExpr* const disablep = nodep->disablep()) { m_disablep = disablep->cloneTreePure(false); if (VN_IS(nodep->backp(), Cover)) { @@ -547,6 +566,7 @@ private: } void visit(AstNodeModule* nodep) override { VL_RESTORER(m_defaultClockingp); + VL_RESTORER(m_defaultDisablep); VL_RESTORER(m_modp); m_defaultClockingp = nullptr; nodep->foreach([&](AstClocking* const clockingp) { @@ -558,6 +578,14 @@ private: m_defaultClockingp = clockingp; } }); + m_defaultDisablep = nullptr; + nodep->foreach([&](AstDefaultDisable* const disablep) { + if (m_defaultDisablep) { + disablep->v3error("Only one 'default disable iff' allowed per module" + " (IEEE 1800-2023 16.15)"); + } + m_defaultDisablep = disablep; + }); m_modp = nodep; iterateChildren(nodep); } diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 4643a5e10..e7c60a61a 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4501,6 +4501,18 @@ public: }; // === AstNodeTermop === +class AstInferredDisable final : public AstNodeTermop { +public: + AstInferredDisable(FileLine* fl) + : ASTGEN_SUPER_InferredDisable(fl) { + dtypeSetLogicSized(1, VSigning::UNSIGNED); + } + ASTGEN_MEMBERS_AstInferredDisable; + string emitVerilog() override { return "%f$inferred_disable"; } + string emitC() override { V3ERROR_NA_RETURN(""); } + bool cleanOut() const override { return true; } + bool same(const AstNode* /*samep*/) const override { return true; } +}; class AstTime final : public AstNodeTermop { VTimescale m_timeunit; // Parent module time unit public: diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 9ac6180b4..c38cc4773 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -1076,6 +1076,16 @@ public: bool same(const AstNode*) const override { return true; } string path() const { return m_path; } }; +class AstDefaultDisable final : public AstNode { + // @astgen op1 := condp : AstNodeExpr + +public: + AstDefaultDisable(FileLine* fl, AstNodeExpr* condp) + : ASTGEN_SUPER_DefaultDisable(fl) { + this->condp(condp); + } + ASTGEN_MEMBERS_AstDefaultDisable; +}; class AstDpiExport final : public AstNode { // We could put an AstNodeFTaskRef instead of the verilog function name, // however we're not *calling* it, so that seems somehow wrong. diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 23d77fae6..00a0d157c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -670,6 +670,11 @@ class WidthVisitor final : public VNVisitor { } } } + void visit(AstDefaultDisable* nodep) override { + assertAtStatement(nodep); + // it's like an if() condition. + iterateCheckBool(nodep, "default disable iff condiftion", nodep->condp(), BOTH); + } void visit(AstDelay* nodep) override { if (VN_IS(m_procedurep, Final)) { nodep->v3error("Delays are not legal in final blocks (IEEE 1800-2023 9.2.3)"); @@ -1391,6 +1396,9 @@ class WidthVisitor final : public VNVisitor { // queue_slice[#:$] and queue_bitsel[$] etc handled in V3WidthSel nodep->v3warn(E_UNSUPPORTED, "Unsupported/illegal unbounded ('$') in this context."); } + void visit(AstInferredDisable* nodep) override { + if (m_vup->prelim()) nodep->dtypeSetBit(); + } void visit(AstIsUnbounded* nodep) override { if (m_vup->prelim()) { userIterateAndNext(nodep->lhsp(), WidthVP{SELF, BOTH}.p()); diff --git a/src/verilog.l b/src/verilog.l index 1092bedcb..b46bdd1bd 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -474,6 +474,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5} "$fell_gclk" { FL; return yD_FELL_GCLK; } "$high" { FL; return yD_HIGH; } "$increment" { FL; return yD_INCREMENT; } + "$inferred_disable" { FL; return yD_INFERRED_DISABLE; } "$info" { FL; return yD_INFO; } "$isunbounded" { FL; return yD_ISUNBOUNDED; } "$isunknown" { FL; return yD_ISUNKNOWN; } diff --git a/src/verilog.y b/src/verilog.y index 745128bd3..792de8573 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -888,6 +888,7 @@ BISONPRE_VERSION(3.7,%define api.header.include {"V3ParseBison.h"}) %token yD_HIGH "$high" %token yD_HYPOT "$hypot" %token yD_INCREMENT "$increment" +%token yD_INFERRED_DISABLE "$inferred_disable" %token yD_INFO "$info" %token yD_ISUNBOUNDED "$isunbounded" %token yD_ISUNKNOWN "$isunknown" @@ -2798,8 +2799,12 @@ module_or_generate_item_declaration: // ==IEEE: module_or_generate_it | clocking_declaration { $$ = $1; } | yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';' { $$ = nullptr; BBUNSUP($1, "Unsupported: default clocking identifier"); } - | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' - { $$ = nullptr; BBUNSUP($1, "Unsupported: default disable iff"); } + | defaultDisable { $$ = $1; } + ; + +defaultDisable: // IEEE: part of module_/checker_or_generate_item_declaration + yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' + { $$ = new AstDefaultDisable{$1, $4}; } ; aliasEqList: // IEEE: part of net_alias @@ -4423,6 +4428,7 @@ system_f_call_or_t: // IEEE: part of system_tf_call (can be task | yD_HYPOT '(' expr ',' expr ')' { $$ = new AstHypotD{$1, $3, $5}; } | yD_INCREMENT '(' exprOrDataType ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_INCREMENT, $3, nullptr}; } | yD_INCREMENT '(' exprOrDataType ',' expr ')' { $$ = new AstAttrOf{$1, VAttrType::DIM_INCREMENT, $3, $5}; } + | yD_INFERRED_DISABLE parenE { $$ = new AstInferredDisable{$1}; } | yD_ISUNBOUNDED '(' expr ')' { $$ = new AstIsUnbounded{$1, $3}; } | yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown{$1, $3}; } | yD_ITOR '(' expr ')' { $$ = new AstIToRD{$1, $3}; } @@ -7113,7 +7119,7 @@ checker_or_generate_item_declaration: // ==IEEE: checker_or_generate_ite | clocking_declaration { $$ = $1; } | yDEFAULT yCLOCKING idAny/*clocking_identifier*/ ';' { } { $$ = nullptr; BBUNSUP($1, "Unsupported: checker default clocking"); } - | yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';' { } + | defaultDisable { $$ = nullptr; BBUNSUP($1, "Unsupported: checker default disable iff"); } | ';' { $$ = nullptr; } ; diff --git a/test_regress/t/t_EXAMPLE.v b/test_regress/t/t_EXAMPLE.v index 75a416220..c3eb28a02 100644 --- a/test_regress/t/t_EXAMPLE.v +++ b/test_regress/t/t_EXAMPLE.v @@ -16,6 +16,9 @@ // any use, without warranty, 2024 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0x exp=%0x (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); + module t(/*AUTOARG*/ // Inputs clk @@ -64,10 +67,9 @@ module t(/*AUTOARG*/ end else if (cyc == 99) begin $write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum); - if (crc !== 64'hc77bb9b3784ea091) $stop; + `checkh(crc, 64'hc77bb9b3784ea091); // What checksum will we end up with (above print should match) -`define EXPECTED_SUM 64'h4afe43fb79d7b71e - if (sum !== `EXPECTED_SUM) $stop; + `checkh(sum, 64'h4afe43fb79d7b71e); $write("*-* All Finished *-*\n"); $finish; end diff --git a/test_regress/t/t_assert_disable_bad.v b/test_regress/t/t_assert_disable_bad.v index 07b3bc342..7bb6c04ad 100644 --- a/test_regress/t/t_assert_disable_bad.v +++ b/test_regress/t/t_assert_disable_bad.v @@ -5,7 +5,8 @@ // SPDX-License-Identifier: CC0-1.0 module t (/*AUTOARG*/ - clk + // Inputs + clk ); input clk; @@ -18,8 +19,7 @@ module t (/*AUTOARG*/ end property check(int cyc_mod_2, logic expected); - @(posedge clk) - disable iff (cyc == 0) cyc % 2 == cyc_mod_2 |=> val == expected; + @(posedge clk) disable iff (cyc == 0) cyc % 2 == cyc_mod_2 |=> val == expected; endproperty // Test should fail due to duplicated disable iff statements diff --git a/test_regress/t/t_assert_disable_count.py b/test_regress/t/t_assert_disable_count.py new file mode 100755 index 000000000..2c4ffdce2 --- /dev/null +++ b/test_regress/t/t_assert_disable_count.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--assert']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_assert_disable_count.v b/test_regress/t/t_assert_disable_count.v new file mode 100644 index 000000000..3a424467c --- /dev/null +++ b/test_regress/t/t_assert_disable_count.v @@ -0,0 +1,69 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + int cyc; + + Sub sub (); + + default disable iff (cyc[0]); + + int a_false; + always @(posedge clk iff !cyc[0]) begin + if (cyc < 4 || cyc > 9) ; + else a_false = a_false + 1; + end + + int a0_false; + a0: assert property (@(posedge clk) disable iff (cyc[0]) (cyc < 4 || cyc > 9)) + else a0_false = a0_false + 1; + + int a1_false; + // Note that Verilator supports $inferred_disable in general expression locations + // This is a superset of what IEEE specifies + a1: assert property (@(posedge clk) disable iff ($inferred_disable) (cyc < 4 || cyc > 9)) + else a1_false = a1_false + 1; + + int a2_false; + // Implicitly uses $inferred_disable + a2: assert property (@(posedge clk) (cyc < 4 || cyc > 9)) + else a2_false = a2_false + 1; + + int a3_false; + // A different disable iff expression + a3: assert property (@(posedge clk) disable iff (cyc == 5) (cyc < 4 || cyc > 9)) + else a3_false = a3_false + 1; + + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 20) begin + `checkd(a_false, 3); + `checkd(a0_false, a_false); + `checkd(a1_false, a_false); + `checkd(a2_false, a_false); + `checkd(a3_false, 5); + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +module Sub; + + initial begin + if ($inferred_disable !== 0) $stop; + end + +endmodule diff --git a/test_regress/t/t_assert_disable_iff.v b/test_regress/t/t_assert_disable_iff.v index 7a5b2b2fd..23ec387bc 100644 --- a/test_regress/t/t_assert_disable_iff.v +++ b/test_regress/t/t_assert_disable_iff.v @@ -10,73 +10,47 @@ module t (/*AUTOARG*/ ); input clk; - integer cyc; initial cyc=1; + int cyc; Test test (/*AUTOINST*/ // Inputs .clk (clk)); - always @ (posedge clk) begin - if (cyc!=0) begin - cyc <= cyc + 1; - if (cyc==10) begin - $write("*-* All Finished *-*\n"); - $finish; - end + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; end end endmodule -module Test - ( - input clk - ); +module Test ( + input clk +); `ifdef FAIL_ASSERT_1 - assert property ( - @(posedge clk) disable iff (0) - 0 - ) else $display("wrong disable"); + assert property (@(posedge clk) disable iff (0) 0) + else $display("wrong disable"); `endif - assert property ( - @(posedge clk) disable iff (1) - 0 - ); + assert property (@(posedge clk) disable iff (1) 0); - assert property ( - @(posedge clk) disable iff (1) - 1 - ); + assert property (@(posedge clk) disable iff (1) 1); - assert property ( - @(posedge clk) disable iff (0) - 1 - ); + assert property (@(posedge clk) disable iff (0) 1); // // Cover properties behave differently // - cover property ( - @(posedge clk) disable iff (1) - 1 - ) $stop; + cover property (@(posedge clk) disable iff (1) 1) $stop; - cover property ( - @(posedge clk) disable iff (1) - 0 - ) $stop; + cover property (@(posedge clk) disable iff (1) 0) $stop; - cover property ( - @(posedge clk) disable iff (0) - 1 - ) $display("*COVER: ok"); + cover property (@(posedge clk) disable iff (0) 1) $display("*COVER: ok"); - cover property ( - @(posedge clk) disable iff (0) - 0 - ) $stop; + cover property (@(posedge clk) disable iff (0) 0) $stop; endmodule diff --git a/test_regress/t/t_disable_iff_multi_bad.out b/test_regress/t/t_disable_iff_multi_bad.out index 24b6b78a6..cf6dedeb4 100644 --- a/test_regress/t/t_disable_iff_multi_bad.out +++ b/test_regress/t/t_disable_iff_multi_bad.out @@ -1,8 +1,5 @@ -%Error-UNSUPPORTED: t/t_disable_iff_multi_bad.v:13:4: Unsupported: default disable iff - 13 | default disable iff (!rstn); - | ^~~~~~~ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_disable_iff_multi_bad.v:14:4: Unsupported: default disable iff +%Error: t/t_disable_iff_multi_bad.v:14:4: Only one 'default disable iff' allowed per module (IEEE 1800-2023 16.15) + : ... note: In instance 't' 14 | default disable iff (!rstn); | ^~~~~~~ %Error: Exiting due to From 94e545bdcaea3f434221870702f04916682bb66e Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Wed, 27 Nov 2024 17:20:21 -0500 Subject: [PATCH 100/171] Fix interface and struct pattern collision (#5640) (#5639) --- src/V3LinkDot.cpp | 14 ++++- .../t/t_interface_and_struct_pattern.py | 18 ++++++ .../t/t_interface_and_struct_pattern.v | 59 +++++++++++++++++++ test_regress/t/t_param_pattern_init.v | 53 ++++++++++++++++- 4 files changed, 138 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_interface_and_struct_pattern.py create mode 100644 test_regress/t/t_interface_and_struct_pattern.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 40aa0a413..d4eb83dbc 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2760,9 +2760,17 @@ class LinkDotResolveVisitor final : public VNVisitor { // Lookup if (VSymEnt* const foundp = m_curSymp->findIdFallback(textp->text())) { if (AstVar* const varp = VN_CAST(foundp->nodep(), Var)) { - // Attach found Text reference to PatMember - nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ}); - UINFO(9, indent() << " new " << nodep->varrefp() << endl); + if (varp->isParam() || varp->isGenVar()) { + // Attach found Text reference to PatMember + nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ}); + UINFO(9, indent() << " new " << nodep->varrefp() << endl); + } + } + if (AstEnumItem* const itemp = VN_CAST(foundp->nodep(), EnumItem)) { + // Attach enum item value to PatMember + nodep->varrefp( + new AstEnumItemRef{nodep->fileline(), itemp, foundp->classOrPackagep()}); + UINFO(9, indent() << " new " << itemp << endl); } } } diff --git a/test_regress/t/t_interface_and_struct_pattern.py b/test_regress/t/t_interface_and_struct_pattern.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_and_struct_pattern.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_and_struct_pattern.v b/test_regress/t/t_interface_and_struct_pattern.v new file mode 100644 index 000000000..2b75dca53 --- /dev/null +++ b/test_regress/t/t_interface_and_struct_pattern.v @@ -0,0 +1,59 @@ +// DESCRIPTION: Verilator: SystemVerilog interface test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Iztok Jeras. +// SPDX-License-Identifier: CC0-1.0 + +package Package_pkg; + typedef struct packed { + int bar; + int baz; + } pkg_struct_t; +endpackage + +interface intf + #(parameter type data_type = bit) + (input wire clk, + input wire rst); + data_type data; + modport source ( + input clk, rst, + output data + ); +endinterface + +module sub ( + intf.source bar, + input clk, + input rst); + + typedef struct packed { + int foo; + int baz; + } struct_t; + + intf #(.data_type(struct_t)) the_intf (.*); + + Package_pkg::pkg_struct_t output_bar = Package_pkg::pkg_struct_t'{ + bar: the_intf.data.foo, + baz: the_intf.data.baz + }; +endmodule + +module t(clk); + input clk; + logic rst; + + intf bar (.*); + sub the_sub ( + .bar(bar), + .clk, + .rst + ); + + // finish report + always @ (posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_param_pattern_init.v b/test_regress/t/t_param_pattern_init.v index 8abd72fc4..f175e4bcf 100644 --- a/test_regress/t/t_param_pattern_init.v +++ b/test_regress/t/t_param_pattern_init.v @@ -7,7 +7,13 @@ `define stop $stop `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); -module t (/*AUTOARG*/); +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + int cyc = 0; localparam int unsigned SPI_INDEX = 0; localparam int unsigned I2C_INDEX = 1; @@ -26,8 +32,49 @@ module t (/*AUTOARG*/); `checkh(AHB_ADDR[3], 32'h0); `checkh(AHB_ADDR[4], 32'h80003000); `checkh(AHB_ADDR[5], 32'h0); - $write("*-* All Finished *-*\n"); - $finish; + end + + genvar genvar_i; + for (genvar_i = 0; genvar_i < 2; genvar_i++) begin: the_gen + logic [31:0] gen_array [10]; + + always_comb gen_array = '{ + genvar_i: 32'habcd, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(gen_array[genvar_i], 32'habcd); + end + end + + typedef enum int { + ENUM_A = 0, + ENUM_B, + ENUM_C + } enum_t; + + logic [31:0] enum_array [11]; + + always_comb enum_array = '{ + ENUM_A: 32'h1234, + ENUM_B: 32'h7777, + ENUM_C: 32'ha5a5, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(enum_array[0], 32'h1234); + `checkh(enum_array[1], 32'h7777); + `checkh(enum_array[2], 32'ha5a5); + end + + always_ff @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 2) begin + $write("*-* All Finished *-*\n"); + $finish; + end end endmodule From 7695687e87b58da77d3928170e45a2531786df04 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 27 Nov 2024 17:26:33 -0500 Subject: [PATCH 101/171] Commentary: Changes update --- Changes | 1 + docs/guide/deprecations.rst | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Changes b/Changes index c650faff4..28d1e558a 100644 --- a/Changes +++ b/Changes @@ -46,6 +46,7 @@ Verilator 5.031 devel * Fix `rand` dynamic arrays with null handles (#5594). [Ryszard Rozak, Antmicro Ltd.] * Fix NBAs to unpacked arrays of unpacked structs (#5603). [Geza Lore] * Fix array of struct member overwrites on member update (#5605) (#5618) (#5628). [sumpster] +* Fix interface and struct pattern collision (#5639) (#5640). [Todd Strader] Verilator 5.030 2024-10-27 diff --git a/docs/guide/deprecations.rst b/docs/guide/deprecations.rst index 881583518..7df77fcf9 100644 --- a/docs/guide/deprecations.rst +++ b/docs/guide/deprecations.rst @@ -13,7 +13,10 @@ C++14 compiler support Verilator will require C++20 or newer compilers for both compiling Verilator and compiling all Verilated models no sooner than May 2025. + (Likely to be removed shortly after GitHub removes Ubuntu 20.04 + continuous-integration action runners, which are used to test the older + C++ standard). XML output Verilator currently supports XML parser output (enabled with `--xml-only`). - Support for `--xml-*` options will be deprecated no sooner than January 2025. + Support for `--xml-*` options will be deprecated no sooner than January 2026. From e0ad430cd95ae600d8f9b605c2675916a71b1d4a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 28 Nov 2024 13:33:59 -0500 Subject: [PATCH 102/171] Internals: V3Slice style cleanup. No functional change; ignore whitespace --- src/V3EmitCConstInit.h | 4 +- src/V3Slice.cpp | 157 ++++++++++++++++++++--------------------- 2 files changed, 79 insertions(+), 82 deletions(-) diff --git a/src/V3EmitCConstInit.h b/src/V3EmitCConstInit.h index b91ab9718..7799aea97 100644 --- a/src/V3EmitCConstInit.h +++ b/src/V3EmitCConstInit.h @@ -50,8 +50,8 @@ protected: m_inUnpacked = true; if (VN_IS(nodep->dtypep()->skipRefp(), AssocArrayDType)) { // Note the double {{ initializer. The first { starts the initializer of the - // VlUnpacked, and the second starts the initializer of m_storage within the - // VlUnpacked. + // VlAssocArray, and the second starts the initializer of m_storage within the + // VlAssocArray. puts("{"); ofp()->putsNoTracking("{"); puts("\n"); diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 434f09e81..c63dd6a25 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -31,7 +31,7 @@ // ARRAYSEL // Modify bitp() for the new value and set ->length(1) // -// TODO: This code was written before SLICESEL was a type it might be +// TODO: This code was written before SLICESEL was a type, it might be // simplified to look primarily for SLICESELs. //************************************************************************* @@ -54,13 +54,12 @@ class SliceVisitor final : public VNVisitor { // AstInitItem::user2() -> Corresponding first elemIdx const VNUser2InUse m_inuser2; - // STATE + // STATE - for current visit position (use VL_RESTORER) AstNode* m_assignp = nullptr; // Assignment we are under bool m_assignError = false; // True if the current assign already has an error bool m_okInitArray = false; // Allow InitArray children // METHODS - AstNodeExpr* cloneAndSel(AstNode* nodep, int elements, int elemIdx) { // Insert an ArraySel, except for a few special cases const AstUnpackArrayDType* const arrayp @@ -221,40 +220,40 @@ class SliceVisitor final : public VNVisitor { void visit(AstNodeAssign* nodep) override { // Called recursively on newly created assignments - if (!nodep->user1() && !VN_IS(nodep, AssignAlias)) { - nodep->user1(true); - m_assignError = false; - if (debug() >= 9) nodep->dumpTree("- Deslice-In: "); - AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); - AstNode* stp = nodep->rhsp(); - if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) { - if (!VN_IS(stp, CvtPackedToArray)) { - // Left and right could have different ascending/descending range, - // but #elements is common and all variables are realigned to start at zero - // Assign of an ascending range slice to a descending range one must reverse - // the elements - AstNodeAssign* newlistp = nullptr; - const int elements = arrayp->rangep()->elementsConst(); - for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { - AstNodeAssign* const newp - = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), - cloneAndSel(nodep->rhsp(), elements, elemIdx)); - if (debug() >= 9) newp->dumpTree("- new: "); - newlistp = AstNode::addNext(newlistp, newp); - } - if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: "); - nodep->replaceWith(newlistp); - VL_DO_DANGLING(nodep->deleteTree(), nodep); - // Normal edit iterator will now iterate on all of the expansion assignments - // This will potentially call this function again to resolve next level of - // slicing - return; + if (nodep->user1SetOnce()) return; // Process once + if (VN_IS(nodep, AssignAlias)) return; + if (debug() >= 9) nodep->dumpTree("- Deslice-In: "); + VL_RESTORER(m_assignError); + VL_RESTORER(m_assignp); + m_assignError = false; + m_assignp = nodep; + AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); + AstNode* stp = nodep->rhsp(); + if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) { + if (!VN_IS(stp, CvtPackedToArray)) { + // Left and right could have different ascending/descending range, + // but #elements is common and all variables are realigned to start at zero + // Assign of an ascending range slice to a descending range one must reverse + // the elements + AstNodeAssign* newlistp = nullptr; + const int elements = arrayp->rangep()->elementsConst(); + for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { + AstNodeAssign* const newp + = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), + cloneAndSel(nodep->rhsp(), elements, elemIdx)); + if (debug() >= 9) newp->dumpTree("- new: "); + newlistp = AstNode::addNext(newlistp, newp); } + if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: "); + nodep->replaceWith(newlistp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + // Normal edit iterator will now iterate on all of the expansion assignments + // This will potentially call this function again to resolve next level of + // slicing + return; } - VL_RESTORER(m_assignp); - m_assignp = nodep; - iterateChildren(nodep); } + iterateChildren(nodep); } void visit(AstConsPackUOrStruct* nodep) override { @@ -278,57 +277,55 @@ class SliceVisitor final : public VNVisitor { } void expandBiOp(AstNodeBiop* nodep) { - if (!nodep->user1()) { - nodep->user1(true); - // If it's an unpacked array, blow it up into comparing each element - AstNodeDType* const fromDtp = nodep->lhsp()->dtypep()->skipRefp(); - UINFO(9, " Bi-Eq/Neq expansion " << nodep << endl); - if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) { - AstNodeBiop* logp = nullptr; - if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) { - nodep->lhsp()->v3error( - "Slice operator " - << nodep->lhsp()->prettyTypeName() - << " on non-slicable (e.g. non-vector) left-hand-side operand"); - } else if (!VN_IS(nodep->rhsp()->dtypep()->skipRefp(), NodeArrayDType)) { - nodep->rhsp()->v3error( - "Slice operator " - << nodep->rhsp()->prettyTypeName() - << " on non-slicable (e.g. non-vector) right-hand-side operand"); - } else { - const int elements = adtypep->rangep()->elementsConst(); - for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { - // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) - AstNodeBiop* const clonep = VN_AS( - nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), - cloneAndSel(nodep->rhsp(), elements, elemIdx)), - NodeBiop); - if (!logp) { - logp = clonep; - } else { - switch (nodep->type()) { - case VNType::atEq: // FALLTHRU - case VNType::atEqCase: - logp = new AstLogAnd{nodep->fileline(), logp, clonep}; - break; - case VNType::atNeq: // FALLTHRU - case VNType::atNeqCase: - logp = new AstLogOr{nodep->fileline(), logp, clonep}; - break; - default: - nodep->v3fatalSrc("Unknown node type processing array slice"); - break; - } + if (nodep->user1SetOnce()) return; // Process once + // If it's an unpacked array, blow it up into comparing each element + AstNodeDType* const fromDtp = nodep->lhsp()->dtypep()->skipRefp(); + UINFO(9, " Bi-Eq/Neq expansion " << nodep << endl); + if (const AstUnpackArrayDType* const adtypep = VN_CAST(fromDtp, UnpackArrayDType)) { + AstNodeBiop* logp = nullptr; + if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) { + nodep->lhsp()->v3error( + "Slice operator " + << nodep->lhsp()->prettyTypeName() + << " on non-slicable (e.g. non-vector) left-hand-side operand"); + } else if (!VN_IS(nodep->rhsp()->dtypep()->skipRefp(), NodeArrayDType)) { + nodep->rhsp()->v3error( + "Slice operator " + << nodep->rhsp()->prettyTypeName() + << " on non-slicable (e.g. non-vector) right-hand-side operand"); + } else { + const int elements = adtypep->rangep()->elementsConst(); + for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { + // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) + AstNodeBiop* const clonep + = VN_AS(nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), + cloneAndSel(nodep->rhsp(), elements, elemIdx)), + NodeBiop); + if (!logp) { + logp = clonep; + } else { + switch (nodep->type()) { + case VNType::atEq: // FALLTHRU + case VNType::atEqCase: + logp = new AstLogAnd{nodep->fileline(), logp, clonep}; + break; + case VNType::atNeq: // FALLTHRU + case VNType::atNeqCase: + logp = new AstLogOr{nodep->fileline(), logp, clonep}; + break; + default: + nodep->v3fatalSrc("Unknown node type processing array slice"); + break; } } - UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range"); - nodep->replaceWith(logp); - VL_DO_DANGLING(pushDeletep(nodep), nodep); - nodep = logp; } + UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range"); + nodep->replaceWith(logp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + nodep = logp; } - iterateChildren(nodep); } + iterateChildren(nodep); } void visit(AstEq* nodep) override { expandBiOp(nodep); } void visit(AstNeq* nodep) override { expandBiOp(nodep); } From 7a8f71e7d8da8b9332498b7f91847bfc93a130c6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 28 Nov 2024 13:49:34 -0500 Subject: [PATCH 103/171] Add `--fno-slice` to disable array assignment slicing (#5644). --- Changes | 3 +- docs/guide/exe_verilator.rst | 2 + src/V3Options.cpp | 1 + src/V3Options.h | 2 + src/V3Slice.cpp | 77 +++++++++++++++++++++----------- test_regress/t/t_opt_slice.py | 18 ++++++++ test_regress/t/t_opt_slice.v | 23 ++++++++++ test_regress/t/t_opt_slice_no.py | 19 ++++++++ 8 files changed, 117 insertions(+), 28 deletions(-) create mode 100755 test_regress/t/t_opt_slice.py create mode 100644 test_regress/t/t_opt_slice.v create mode 100755 test_regress/t/t_opt_slice_no.py diff --git a/Changes b/Changes index 28d1e558a..a0e6292c0 100644 --- a/Changes +++ b/Changes @@ -24,6 +24,8 @@ Verilator 5.031 devel * Add `--no-std-package` as subset-alias of `--no-std` (#5607). * Add `lint_off --contents` in configuration files (#5606). * Add `--waiver-multiline` for context-sensitive `--waiver-output` (#5608). +* Add `--fno-inline-funcs` to disable function inlining. +* Add `--fno-slice` to disable array assignment slicing (#5644). * Add error on illegal enum base type (#3010). [Iztok Jeras] * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] @@ -31,7 +33,6 @@ Verilator 5.031 devel * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add error on `solve before` or soft constraints of `randc` variable. -* Add `--fno-inline-funcs` to disable function inlining. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Fix dotted reference in delay value (#2410). * Fix `function fork...join_none` regression with unknown type (#4449). diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 5b9aaf3f0..7a88b6180 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -617,6 +617,8 @@ Summary: .. option:: -fno-reorder +.. option:: -fno-slice + .. option:: -fno-split .. option:: -fno-subst diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 01b57af48..422c09a30 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -1332,6 +1332,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, DECL_OPTION("-fmerge-const-pool", FOnOff, &m_fMergeConstPool); DECL_OPTION("-freloop", FOnOff, &m_fReloop); DECL_OPTION("-freorder", FOnOff, &m_fReorder); + DECL_OPTION("-fslice", FOnOff, &m_fSlice); DECL_OPTION("-fsplit", FOnOff, &m_fSplit); DECL_OPTION("-fsubst", FOnOff, &m_fSubst); DECL_OPTION("-fsubst-const", FOnOff, &m_fSubstConst); diff --git a/src/V3Options.h b/src/V3Options.h index f7a05a022..a1e9b1b0c 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -399,6 +399,7 @@ private: bool m_fMergeConstPool = true; // main switch: -fno-merge-const-pool bool m_fReloop; // main switch: -fno-reloop: reform loops bool m_fReorder; // main switch: -fno-reorder: reorder assignments in blocks + bool m_fSlice = true; // main switch: -fno-slice: array assignment slicing bool m_fSplit; // main switch: -fno-split: always assignment splitting bool m_fSubst; // main switch: -fno-subst: substitute expression temp values bool m_fSubstConst; // main switch: -fno-subst-const: final constant substitution @@ -696,6 +697,7 @@ public: bool fMergeConstPool() const { return m_fMergeConstPool; } bool fReloop() const { return m_fReloop; } bool fReorder() const { return m_fReorder; } + bool fSlice() const { return m_fSlice; } bool fSplit() const { return m_fSplit; } bool fSubst() const { return m_fSubst; } bool fSubstConst() const { return m_fSubstConst; } diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index c63dd6a25..c9f6238a5 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -39,6 +39,8 @@ #include "V3Slice.h" +#include "V3Stats.h" + VL_DEFINE_DEBUG_FUNCTIONS; //************************************************************************* @@ -54,6 +56,9 @@ class SliceVisitor final : public VNVisitor { // AstInitItem::user2() -> Corresponding first elemIdx const VNUser2InUse m_inuser2; + // STATE - across all visitors + VDouble0 m_statAssigns; // Statistic tracking + // STATE - for current visit position (use VL_RESTORER) AstNode* m_assignp = nullptr; // Assignment we are under bool m_assignError = false; // True if the current assign already has an error @@ -218,6 +223,46 @@ class SliceVisitor final : public VNVisitor { return newp; } + bool assignOptimize(AstNodeAssign* nodep) { + // Return true if did optimization + AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); + AstNode* stp = nodep->rhsp(); + const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType); + if (!arrayp) return false; + if (VN_IS(stp, CvtPackedToArray)) return false; + + // Any isSc variables must be expanded regardless of --fno-slice + const bool hasSc + = nodep->exists([&](const AstVarRef* refp) -> bool { return refp->varp()->isSc(); }); + if (!hasSc && !v3Global.opt.fSlice()) { + m_okInitArray = true; // VL_RESTORER in visit(AstNodeAssign) + return false; + } + + UINFO(4, "Slice optimizing " << nodep << endl); + ++m_statAssigns; + + // Left and right could have different ascending/descending range, + // but #elements is common and all variables are realigned to start at zero + // Assign of an ascending range slice to a descending range one must reverse + // the elements + AstNodeAssign* newlistp = nullptr; + const int elements = arrayp->rangep()->elementsConst(); + for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { + AstNodeAssign* const newp + = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), + cloneAndSel(nodep->rhsp(), elements, elemIdx)); + if (debug() >= 9) newp->dumpTree("- new: "); + newlistp = AstNode::addNext(newlistp, newp); + } + if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: "); + nodep->replaceWith(newlistp); + VL_DO_DANGLING(nodep->deleteTree(), nodep); + // Normal edit iterator will now iterate on all of the expansion assignments + // This will potentially call this function again to resolve next level of slicing + return true; + } + void visit(AstNodeAssign* nodep) override { // Called recursively on newly created assignments if (nodep->user1SetOnce()) return; // Process once @@ -225,34 +270,10 @@ class SliceVisitor final : public VNVisitor { if (debug() >= 9) nodep->dumpTree("- Deslice-In: "); VL_RESTORER(m_assignError); VL_RESTORER(m_assignp); + VL_RESTORER(m_okInitArray); // Set in assignOptimize m_assignError = false; m_assignp = nodep; - AstNodeDType* const dtp = nodep->lhsp()->dtypep()->skipRefp(); - AstNode* stp = nodep->rhsp(); - if (const AstUnpackArrayDType* const arrayp = VN_CAST(dtp, UnpackArrayDType)) { - if (!VN_IS(stp, CvtPackedToArray)) { - // Left and right could have different ascending/descending range, - // but #elements is common and all variables are realigned to start at zero - // Assign of an ascending range slice to a descending range one must reverse - // the elements - AstNodeAssign* newlistp = nullptr; - const int elements = arrayp->rangep()->elementsConst(); - for (int elemIdx = 0; elemIdx < elements; ++elemIdx) { - AstNodeAssign* const newp - = nodep->cloneType(cloneAndSel(nodep->lhsp(), elements, elemIdx), - cloneAndSel(nodep->rhsp(), elements, elemIdx)); - if (debug() >= 9) newp->dumpTree("- new: "); - newlistp = AstNode::addNext(newlistp, newp); - } - if (debug() >= 9) nodep->dumpTree("- Deslice-Dn: "); - nodep->replaceWith(newlistp); - VL_DO_DANGLING(nodep->deleteTree(), nodep); - // Normal edit iterator will now iterate on all of the expansion assignments - // This will potentially call this function again to resolve next level of - // slicing - return; - } - } + if (assignOptimize(nodep)) return; iterateChildren(nodep); } @@ -337,7 +358,9 @@ class SliceVisitor final : public VNVisitor { public: // CONSTRUCTORS explicit SliceVisitor(AstNetlist* nodep) { iterate(nodep); } - ~SliceVisitor() override = default; + ~SliceVisitor() override { + V3Stats::addStat("Optimizations, Slice array assignments", m_statAssigns); + } }; //###################################################################### diff --git a/test_regress/t/t_opt_slice.py b/test_regress/t/t_opt_slice.py new file mode 100755 index 000000000..b39ad3229 --- /dev/null +++ b/test_regress/t/t_opt_slice.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--sc', '--stats']) + +test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 3) + +test.passes() diff --git a/test_regress/t/t_opt_slice.v b/test_regress/t/t_opt_slice.v new file mode 100644 index 000000000..92ac3dd37 --- /dev/null +++ b/test_regress/t/t_opt_slice.v @@ -0,0 +1,23 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Outputs + o1a2, + // Inputs + i1a2 + ); + + input i1a2 [1:0]; + output logic o1a2 [1:0]; + + always o1a2 = i1a2; + + initial begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_opt_slice_no.py b/test_regress/t/t_opt_slice_no.py new file mode 100755 index 000000000..3ee92e4e0 --- /dev/null +++ b/test_regress/t/t_opt_slice_no.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = 't/t_opt_slice.v' + +test.compile(verilator_flags2=['--sc', '--stats', '-fno-slice']) + +test.file_grep(test.stats, r'Optimizations, Slice array assignments\s+(\d+)', 2) + +test.passes() From d1656712257ed73552a110bc284c695b6b82dd38 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 28 Nov 2024 14:09:06 -0500 Subject: [PATCH 104/171] Improve error when no parameter type value (#5645 partial) --- src/V3Param.cpp | 15 ++++++++++++--- test_regress/t/t_class_param_bad2.out | 6 +++++- test_regress/t/t_class_param_noinit_bad.out | 9 +++++++-- test_regress/t/t_class_param_noinit_bad.v | 2 +- .../t/t_lint_iface_array_topmodule_bad.out | 2 +- test_regress/t/t_lint_iface_topmodule_bad.out | 2 +- test_regress/t/t_param_default_bad.out | 2 +- test_regress/t/t_param_default_presv_bad.out | 2 +- test_regress/t/t_param_noval_bad.out | 8 ++++++-- test_regress/t/t_param_noval_bad.v | 2 +- 10 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/V3Param.cpp b/src/V3Param.cpp index fe580f853..d427c4f58 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -924,13 +924,15 @@ class ParamProcessor final { for (auto* stmtp = srcModpr->stmtsp(); stmtp; stmtp = stmtp->nextp()) { if (AstParamTypeDType* dtypep = VN_CAST(stmtp, ParamTypeDType)) { if (VN_IS(dtypep->subDTypep(), VoidDType)) { - nodep->v3error("Missing type parameter: " << dtypep->prettyNameQ()); + nodep->v3error( + "Class parameter type without default value is never given value" + << " (IEEE 1800-2023 6.20.1): " << dtypep->prettyNameQ()); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } } if (AstVar* const varp = VN_CAST(stmtp, Var)) { if (VN_IS(srcModpr, Class) && varp->isParam() && !varp->valuep()) { - nodep->v3error("Class parameter without initial value is never given value" + nodep->v3error("Class parameter without default value is never given value" << " (IEEE 1800-2023 6.20.1): " << varp->prettyNameQ()); } } @@ -1200,13 +1202,20 @@ class ParamVisitor final : public VNVisitor { iterateChildren(nodep); if (nodep->isParam()) { if (!nodep->valuep() && !VN_IS(m_modp, Class)) { - nodep->v3error("Parameter without initial value is never given value" + nodep->v3error("Parameter without default value is never given value" << " (IEEE 1800-2023 6.20.1): " << nodep->prettyNameQ()); } else { V3Const::constifyParamsEdit(nodep); // The variable, not just the var->init() } } } + void visit(AstParamTypeDType* nodep) override { + iterateChildren(nodep); + if (VN_IS(nodep->subDTypep(), VoidDType)) { + nodep->v3error("Parameter type without default value is never given value" + << " (IEEE 1800-2023 6.20.1): " << nodep->prettyNameQ()); + } + } // Make sure varrefs cause vars to constify before things above void visit(AstVarRef* nodep) override { // Might jump across functions, so beware if ever add a m_funcp diff --git a/test_regress/t/t_class_param_bad2.out b/test_regress/t/t_class_param_bad2.out index 1eadc4902..6def63ba0 100644 --- a/test_regress/t/t_class_param_bad2.out +++ b/test_regress/t/t_class_param_bad2.out @@ -1,5 +1,9 @@ -%Error: t/t_class_param_bad2.v:12:4: Missing type parameter: 'PARAMB' +%Error: t/t_class_param_bad2.v:12:4: Class parameter type without default value is never given value (IEEE 1800-2023 6.20.1): 'PARAMB' : ... note: In instance 't' 12 | Cls c; | ^~~ +%Error: t/t_class_param_bad2.v:7:18: Parameter type without default value is never given value (IEEE 1800-2023 6.20.1): 'PARAMB' + : ... note: In instance 't' + 7 | class Cls #(type PARAMB); + | ^~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_param_noinit_bad.out b/test_regress/t/t_class_param_noinit_bad.out index 3495bc6aa..c3e85d2f3 100644 --- a/test_regress/t/t_class_param_noinit_bad.out +++ b/test_regress/t/t_class_param_noinit_bad.out @@ -1,5 +1,10 @@ -%Error: t/t_class_param_noinit_bad.v:13:7: Class parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'B' +%Error: t/t_class_param_noinit_bad.v:13:7: Class parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'B' : ... note: In instance 't' 13 | Cls #(1) c; | ^~~ -%Error: Exiting due to +%Error: t/t_class_param_noinit_bad.v:13:7: Class parameter type without default value is never given value (IEEE 1800-2023 6.20.1): 'T' + : ... note: In instance 't' + 13 | Cls #(1) c; + | ^~~ +%Error: Verilator internal fault, sorry. Suggest trying --debug --gdbbt +%Error: Command Failed diff --git a/test_regress/t/t_class_param_noinit_bad.v b/test_regress/t/t_class_param_noinit_bad.v index 52398d589..856842f33 100644 --- a/test_regress/t/t_class_param_noinit_bad.v +++ b/test_regress/t/t_class_param_noinit_bad.v @@ -5,7 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 // No init value is legal with classes, as long as not used without the parameter -class Cls #(int A, int B); +class Cls #(int A, int B, type T); endclass module t(/*AUTOARG*/); diff --git a/test_regress/t/t_lint_iface_array_topmodule_bad.out b/test_regress/t/t_lint_iface_array_topmodule_bad.out index 15778c71b..dda9a0753 100644 --- a/test_regress/t/t_lint_iface_array_topmodule_bad.out +++ b/test_regress/t/t_lint_iface_array_topmodule_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_lint_iface_array_topmodule_bad.v:8:24: Parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'DW' +%Error: t/t_lint_iface_array_topmodule_bad.v:8:24: Parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'DW' : ... note: In instance 't' 8 | parameter integer DW | ^~ diff --git a/test_regress/t/t_lint_iface_topmodule_bad.out b/test_regress/t/t_lint_iface_topmodule_bad.out index b7a2efc8d..617ac75a9 100644 --- a/test_regress/t/t_lint_iface_topmodule_bad.out +++ b/test_regress/t/t_lint_iface_topmodule_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_lint_iface_topmodule_bad.v:8:23: Parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'DW' +%Error: t/t_lint_iface_topmodule_bad.v:8:23: Parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'DW' : ... note: In instance 't' 8 | parameter integer DW | ^~ diff --git a/test_regress/t/t_param_default_bad.out b/test_regress/t/t_param_default_bad.out index b08438467..b4a331abb 100644 --- a/test_regress/t/t_param_default_bad.out +++ b/test_regress/t/t_param_default_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_param_default_bad.v:7:26: Parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'Foo' +%Error: t/t_param_default_bad.v:7:26: Parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'Foo' : ... note: In instance 't.foo' 7 | module m #(parameter int Foo); | ^~~ diff --git a/test_regress/t/t_param_default_presv_bad.out b/test_regress/t/t_param_default_presv_bad.out index 60432957c..6a1db2f52 100644 --- a/test_regress/t/t_param_default_presv_bad.out +++ b/test_regress/t/t_param_default_presv_bad.out @@ -3,7 +3,7 @@ | ^~~ ... For warning description see https://verilator.org/warn/NEWERSTD?v=latest ... Use "/* verilator lint_off NEWERSTD */" and lint_on around source to disable this message. -%Error: t/t_param_default_bad.v:7:26: Parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'Foo' +%Error: t/t_param_default_bad.v:7:26: Parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'Foo' : ... note: In instance 't.foo' 7 | module m #(parameter int Foo); | ^~~ diff --git a/test_regress/t/t_param_noval_bad.out b/test_regress/t/t_param_noval_bad.out index 432b48da8..14072fd52 100644 --- a/test_regress/t/t_param_noval_bad.out +++ b/test_regress/t/t_param_noval_bad.out @@ -1,7 +1,11 @@ -%Error: t/t_param_noval_bad.v:7:22: Parameter without initial value is never given value (IEEE 1800-2023 6.20.1): 'P' +%Error: t/t_param_noval_bad.v:7:22: Parameter without default value is never given value (IEEE 1800-2023 6.20.1): 'P' : ... note: In instance 't' - 7 | module t #(parameter P); + 7 | module t #(parameter P, parameter type T); | ^ +%Error: t/t_param_noval_bad.v:7:40: Parameter type without default value is never given value (IEEE 1800-2023 6.20.1): 'T' + : ... note: In instance 't' + 7 | module t #(parameter P, parameter type T); + | ^ %Warning-WIDTHTRUNC: t/t_param_noval_bad.v:10:7: Logical operator GENFOR expects 1 bit on the For Test Condition, but For Test Condition's VARREF 'P' generates 32 bits. : ... note: In instance 't' 10 | for (j=0; P; j++) diff --git a/test_regress/t/t_param_noval_bad.v b/test_regress/t/t_param_noval_bad.v index 3dde4948a..61248d8ef 100644 --- a/test_regress/t/t_param_noval_bad.v +++ b/test_regress/t/t_param_noval_bad.v @@ -4,7 +4,7 @@ // any use, without warranty, 2019 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 -module t #(parameter P); +module t #(parameter P, parameter type T); generate var j; for (j=0; P; j++) From 8db9db7e2524dff5969cc2b6260522c2ace872d4 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 28 Nov 2024 14:37:11 -0500 Subject: [PATCH 105/171] Internals: Rename same() function. No functional change. --- src/V3Ast.cpp | 2 +- src/V3Ast.h | 4 +- src/V3AstInlines.h | 2 +- src/V3AstNodeDType.h | 46 +++++++------- src/V3AstNodeExpr.h | 148 +++++++++++++++++++++---------------------- src/V3AstNodeOther.h | 116 ++++++++++++++++----------------- src/V3AstNodes.cpp | 20 +++--- src/V3Const.cpp | 2 +- src/V3Gate.cpp | 2 +- 9 files changed, 171 insertions(+), 171 deletions(-) diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 9a3ce06e8..6ad2e4ef4 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1101,7 +1101,7 @@ bool AstNode::sameTreeIter(const AstNode* node1p, const AstNode* node2p, bool ig (!node1p->dtypep() && !node2p->dtypep()) || (node1p->dtypep() && node2p->dtypep()), node1p, "Comparison of a node with dtypep() with a node without dtypep()\n-node2=" << node2p); if (node1p->dtypep() && !node1p->dtypep()->similarDType(node2p->dtypep())) return false; - if (!node1p->same(node2p) || (gateOnly && !node1p->isGateOptimizable())) return false; + if (!node1p->sameNode(node2p) || (gateOnly && !node1p->isGateOptimizable())) return false; return (sameTreeIter(node1p->m_op1p, node2p->m_op1p, false, gateOnly) && sameTreeIter(node1p->m_op2p, node2p->m_op2p, false, gateOnly) && sameTreeIter(node1p->m_op3p, node2p->m_op3p, false, gateOnly) diff --git a/src/V3Ast.h b/src/V3Ast.h index 4b433236a..66466376b 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2122,7 +2122,7 @@ protected: } // Use instead isSame(), this is for each Ast* class, and assumes node is of same type - virtual bool same(const AstNode*) const { return true; } + virtual bool sameNode(const AstNode*) const { return true; } public: // ACCESSORS @@ -2502,7 +2502,7 @@ public: virtual int instrCount() const { return 0; } // Iff node is identical to another node virtual bool isSame(const AstNode* samep) const { - return type() == samep->type() && same(samep); + return type() == samep->type() && sameNode(samep); } // Iff has a data type; dtype() must be non null virtual bool hasDType() const VL_MT_SAFE { return false; } diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 7e55bee79..8759e1bea 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -172,7 +172,7 @@ AstVarRef::AstVarRef(FileLine* fl, AstVarScope* varscp, const VAccess& access) string AstVarRef::name() const { return varp() ? varp()->name() : ""; } -bool AstVarRef::same(const AstVarRef* samep) const { +bool AstVarRef::sameNode(const AstVarRef* samep) const { if (varScopep()) { return (varScopep() == samep->varScopep() && access() == samep->access()); } else { diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 4c0aeae79..3e419d09f 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -64,11 +64,11 @@ public: virtual bool isIntegralOrPacked() const { return !isCompound(); } // (Slow) recurse down to find basic data type virtual AstBasicDType* basicp() const VL_MT_STABLE = 0; - // recurses over typedefs/const/enum to next non-typeref type + // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|ConstDType|EnumDType to other type virtual AstNodeDType* skipRefp() const VL_MT_STABLE = 0; - // recurses over typedefs to next non-typeref-or-const type + // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|EnumDType to ConstDType virtual AstNodeDType* skipRefToConstp() const = 0; - // recurses over typedefs/const to next non-typeref-or-enum/struct type + // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|ConstDType to EnumDType virtual AstNodeDType* skipRefToEnump() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthAlignBytes() const = 0; @@ -155,7 +155,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType); return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep() && rangenp()->sameTree(asamep->rangenp())); @@ -311,7 +311,7 @@ public: BROKEN_RTN(!((m_keyDTypep && !childDTypep()) || (!m_keyDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstAssocArrayDType* const asamep = VN_DBG_AS(samep, AssocArrayDType); if (!asamep->subDTypep()) return false; if (!asamep->keyDTypep()) return false; @@ -392,9 +392,9 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; // width/widthMin/numeric compared elsewhere - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; bool similarDType(const AstNodeDType* samep) const override { - return type() == samep->type() && same(samep); + return type() == samep->type() && sameNode(samep); } string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); } string prettyDTypeName(bool full) const override; @@ -482,7 +482,7 @@ public: this->elementsp(elementsp); } ASTGEN_MEMBERS_AstBracketArrayDType; - bool similarDType(const AstNodeDType* samep) const override { return same(samep); } + bool similarDType(const AstNodeDType* samep) const override { return sameNode(samep); } AstNodeDType* subDTypep() const override VL_MT_STABLE { return childDTypep(); } // METHODS // Will be removed in V3Width, which relies on this @@ -508,11 +508,11 @@ public: public: ASTGEN_MEMBERS_AstCDType; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstCDType* const asamep = VN_DBG_AS(samep, CDType); return m_name == asamep->m_name; } - bool similarDType(const AstNodeDType* samep) const override { return same(samep); } + bool similarDType(const AstNodeDType* samep) const override { return sameNode(samep); } string name() const override VL_MT_STABLE { return m_name; } string prettyDTypeName(bool) const override { return m_name; } // METHODS @@ -551,12 +551,12 @@ public: } ASTGEN_MEMBERS_AstClassRefDType; // METHODS - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType); return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep); } bool similarDType(const AstNodeDType* samep) const override { - return this == samep || (type() == samep->type() && same(samep)); + return this == samep || (type() == samep->type() && sameNode(samep)); } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; @@ -598,7 +598,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstConstDType* const sp = VN_DBG_AS(samep, ConstDType); return (m_refDTypep == sp->m_refDTypep); } @@ -677,12 +677,12 @@ public: , m_uniqueNum(uniqueNumInc()) {} ASTGEN_MEMBERS_AstDefImplicitDType; int uniqueNum() const { return m_uniqueNum; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstDefImplicitDType* const sp = VN_DBG_AS(samep, DefImplicitDType); return uniqueNum() == sp->uniqueNum(); } bool similarDType(const AstNodeDType* samep) const override { - return type() == samep->type() && same(samep); + return type() == samep->type() && sameNode(samep); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { @@ -724,7 +724,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstDynArrayDType* const asamep = VN_DBG_AS(samep, DynArrayDType); if (!asamep->subDTypep()) return false; return subDTypep() == asamep->subDTypep(); @@ -812,7 +812,7 @@ public: const char* broken() const override; int uniqueNum() const { return m_uniqueNum; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstEnumDType* const sp = VN_DBG_AS(samep, EnumDType); return uniqueNum() == sp->uniqueNum(); } @@ -1106,7 +1106,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstQueueDType* const asamep = VN_DBG_AS(samep, QueueDType); if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); @@ -1169,7 +1169,7 @@ public: } ASTGEN_MEMBERS_AstRefDType; // METHODS - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstRefDType* const asamep = VN_DBG_AS(samep, RefDType); return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep && m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep); @@ -1245,7 +1245,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstSampleQueueDType* const asamep = VN_DBG_AS(samep, SampleQueueDType); if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); @@ -1324,7 +1324,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; bool similarDType(const AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } @@ -1387,7 +1387,7 @@ public: BROKEN_RTN(!((m_refDTypep && !childDTypep()) || (!m_refDTypep && childDTypep()))); return nullptr; } - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; bool similarDType(const AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } @@ -1442,7 +1442,7 @@ public: } ASTGEN_MEMBERS_AstUnpackArrayDType; string prettyDTypeName(bool full) const override; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstUnpackArrayDType* const sp = VN_DBG_AS(samep, UnpackArrayDType); return m_isCompound == sp->m_isCompound; } diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index e7c60a61a..69e4d675c 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -99,7 +99,7 @@ public: virtual bool signedFlavor() const { return false; } virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? int instrCount() const override { return widthInstrs(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } bool isPure() override; const char* broken() const override; @@ -203,7 +203,7 @@ public: void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; int instrCount() const override { return INSTR_COUNT_CALL; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstNodeCCall* const asamep = VN_DBG_AS(samep, NodeCCall); return (funcp() == asamep->funcp() && argTypes() == asamep->argTypes()); } @@ -296,7 +296,7 @@ protected: public: ASTGEN_MEMBERS_AstNodePreSel; // METHODS - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } string emitVerilog() final override { V3ERROR_NA_RETURN(""); } string emitC() final override { V3ERROR_NA_RETURN(""); } @@ -343,7 +343,7 @@ public: virtual bool sizeMattersThs() const = 0; // True if output result depends on ths size virtual bool sizeMattersFhs() const = 0; // True if output result depends on ths size int instrCount() const override { return widthInstrs(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } bool isPure() override; const char* broken() const override; @@ -397,7 +397,7 @@ public: virtual bool sizeMattersRhs() const = 0; // True if output result depends on rhs size virtual bool sizeMattersThs() const = 0; // True if output result depends on ths size int instrCount() const override { return widthInstrs(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } bool isPure() override; const char* broken() const override; @@ -478,7 +478,7 @@ public: virtual bool signedFlavor() const { return false; } virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors? int instrCount() const override { return widthInstrs(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } bool isPure() override; const char* broken() const override; }; @@ -629,7 +629,7 @@ public: bool cleanOut() const override { return m_cleanOut; } string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool isPure() override { return pure(); } bool pure() const { return m_pure; } void pure(bool flag) { m_pure = flag; } @@ -653,7 +653,7 @@ public: ASTGEN_MEMBERS_AstCMethodHard; string name() const override VL_MT_STABLE { return m_name; } // * = Var name void name(const string& name) override { m_name = name; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstCMethodHard* const asamep = VN_DBG_AS(samep, CMethodHard); return (m_name == asamep->m_name); } @@ -773,7 +773,7 @@ public: } ASTGEN_MEMBERS_AstClassOrPackageRef; // METHODS - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return (m_classOrPackageNodep == VN_DBG_AS(samep, ClassOrPackageRef)->m_classOrPackageNodep); } @@ -804,7 +804,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstConsDynArray final : public AstNodeExpr { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} @@ -836,7 +836,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstConsDynArray* const sp = VN_DBG_AS(samep, ConsDynArray); return m_lhsIsValue == sp->m_lhsIsValue && m_rhsIsValue == sp->m_rhsIsValue; } @@ -863,7 +863,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstConsPackUOrStruct final : public AstNodeExpr { // Construct a packed struct and return object, '{member1: value1, member2: value2} @@ -886,7 +886,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstConsQueue final : public AstNodeExpr { // Construct a queue and return object, '{}. '{lhs}, '{lhs. rhs} @@ -918,7 +918,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstConsQueue* const sp = VN_DBG_AS(samep, ConsQueue); return m_lhsIsValue == sp->m_lhsIsValue && m_rhsIsValue == sp->m_rhsIsValue; } @@ -939,7 +939,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstConst final : public AstNodeExpr { // A constant @@ -1084,7 +1084,7 @@ public: string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstConst* const sp = VN_DBG_AS(samep, Const); return num().isCaseEq(sp->num()); } @@ -1222,7 +1222,7 @@ public: ASTGEN_MEMBERS_AstEmptyQueue; string emitC() override { V3ERROR_NA_RETURN(""); } string emitVerilog() override { return "{}"; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool cleanOut() const override { return true; } }; class AstEnumItemRef final : public AstNodeExpr { @@ -1240,7 +1240,7 @@ public: void dumpJson(std::ostream& str) const override; string name() const override VL_MT_STABLE { return itemp()->name(); } int instrCount() const override { return 0; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstEnumItemRef* const sp = VN_DBG_AS(samep, EnumItemRef); return itemp() == sp->itemp(); } @@ -1273,7 +1273,7 @@ public: if (AstNode::afterCommentp(stmtsp())) return false; return resultp()->isPure(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } }; class AstFError final : public AstNodeExpr { // @astgen op1 := filep : AstNode @@ -1291,7 +1291,7 @@ public: int instrCount() const override { return widthInstrs() * 64; } bool isPredictOptimizable() const override { return false; } bool isPure() override { return false; } // SPECIAL: $display has 'visual' ordering - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFOpen final : public AstNodeExpr { // @astgen op2 := filenamep : AstNodeExpr @@ -1312,7 +1312,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFOpenMcd final : public AstNodeExpr { // @astgen op2 := filenamep : AstNodeExpr @@ -1331,7 +1331,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFRead final : public AstNodeExpr { // @astgen op1 := memp : AstNode // VarRef for result @@ -1355,7 +1355,7 @@ public: bool isPure() override { return false; } // SPECIAL: has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFRewind final : public AstNodeExpr { // @astgen op1 := filep : Optional[AstNode] @@ -1374,7 +1374,7 @@ public: bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } bool cleanOut() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFScanF final : public AstNodeExpr { // @astgen op1 := exprsp : List[AstNode] // VarRefs for results @@ -1398,7 +1398,7 @@ public: bool isPure() override { return false; } // SPECIAL: has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return text() == VN_DBG_AS(samep, FScanF)->text(); } string text() const { return m_text; } // * = Text to display @@ -1424,7 +1424,7 @@ public: bool isPure() override { return false; } // SPECIAL: has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFTell final : public AstNodeExpr { // @astgen op1 := filep : AstNode // file (must be a VarRef) @@ -1443,7 +1443,7 @@ public: bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } bool cleanOut() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFell final : public AstNodeExpr { // Verilog $fell @@ -1461,7 +1461,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstGatePin final : public AstNodeExpr { // Possibly expand a gate primitive input pin value to match the range of the gate primitive @@ -1497,7 +1497,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstInitArray final : public AstNodeExpr { // This is also used as an array value in V3Simulate/const prop. @@ -1529,7 +1529,7 @@ public: void dumpJson(std::ostream& str) const override; const char* broken() const override; void cloneRelink() override; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { // Only works if exact same children, instead should override comparison // of children list, and instead use map-vs-map key/value compare return m_map == VN_DBG_AS(samep, InitArray)->m_map; @@ -1589,7 +1589,7 @@ public: : ASTGEN_SUPER_LambdaArgRef(fl) , m_name{name} , m_index(index) {} - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } string emitVerilog() override { return name(); } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } @@ -1623,7 +1623,7 @@ public: string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; int instrCount() const override { return widthInstrs(); } AstVar* varp() const { return m_varp; } void varp(AstVar* nodep) { m_varp = nodep; } @@ -1641,7 +1641,7 @@ public: string emitVerilog() override { return "new"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } }; class AstNewDynamic final : public AstNodeExpr { @@ -1659,7 +1659,7 @@ public: string emitVerilog() override { return "new"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } }; class AstParseHolder final : public AstNodeExpr { @@ -1696,7 +1696,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; string name() const override VL_MT_STABLE { return m_name; } // * = Var name - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstParseRef* const asamep = VN_DBG_AS(samep, ParseRef); return (expect() == asamep->expect() && m_name == asamep->m_name); } @@ -1725,7 +1725,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstPatMember final : public AstNodeExpr { // Verilog '{a} or '{a{b}} @@ -1826,7 +1826,7 @@ public: bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool combinable(const AstRand* samep) const { return !seedp() && !samep->seedp() && reset() == samep->reset() && urandom() == samep->urandom(); @@ -1852,7 +1852,7 @@ public: bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstRose final : public AstNodeExpr { // Verilog $rose @@ -1870,7 +1870,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstSFormatF final : public AstNodeExpr { // Convert format to string, generally under an AstDisplay or AstSFormat @@ -1907,7 +1907,7 @@ public: ASTGEN_MEMBERS_AstSFormatF; string name() const override VL_MT_STABLE { return m_text; } int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return text() == VN_DBG_AS(samep, SFormatF)->text(); } string verilogKwd() const override { return "$sformatf"; } @@ -1949,7 +1949,7 @@ public: bool isPure() override { return false; } // SPECIAL: has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: makes output bool cleanOut() const override { return false; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return text() == VN_DBG_AS(samep, SScanF)->text(); } string text() const { return m_text; } // * = Text to display @@ -1969,7 +1969,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return 0; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstScopeName final : public AstNodeExpr { // For display %m and DPI context imports @@ -1989,7 +1989,7 @@ public: dtypeSetUInt64(); } ASTGEN_MEMBERS_AstScopeName; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstScopeName* const sp = VN_DBG_AS(samep, ScopeName); return (m_dpiExport == sp->m_dpiExport && m_forFormat == sp->m_forFormat); } @@ -2027,7 +2027,7 @@ public: this->addElementsp(elementsp); } ASTGEN_MEMBERS_AstSelLoopVars; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool maybePointedTo() const override VL_MT_SAFE { return false; } string emitVerilog() override { V3ERROR_NA_RETURN(""); } @@ -2053,7 +2053,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstSetWildcard final : public AstNodeExpr { // Set a wildcard assoc array element and return object, '{} @@ -2073,7 +2073,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstStable final : public AstNodeExpr { // Verilog $stable @@ -2091,7 +2091,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { V3ERROR_NA_RETURN(""); } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstStackTraceF final : public AstNodeExpr { // $stacktrace used as function @@ -2110,7 +2110,7 @@ public: bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstStructSel final : public AstNodeExpr { // Unpacked struct/union member access @@ -2134,7 +2134,7 @@ public: // Not a union return VN_IS(fromp()->dtypep()->skipRefp(), StructDType); } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstStructSel* const sp = VN_DBG_AS(samep, StructSel); return m_name == sp->m_name; } @@ -2177,7 +2177,7 @@ public: bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstTestPlusArgs final : public AstNodeExpr { // Search expression. If nullptr then this is a $test$plusargs instead of $value$plusargs. @@ -2195,7 +2195,7 @@ public: bool isPredictOptimizable() const override { return false; } // but isPure() true bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstThisRef final : public AstNodeExpr { // Reference to 'this'. @@ -2212,7 +2212,7 @@ public: ASTGEN_MEMBERS_AstThisRef; string emitC() override { return "this"; } string emitVerilog() override { return "this"; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool cleanOut() const override { return true; } AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const VL_MT_STABLE { return dtypep() ? dtypep() : childDTypep(); } @@ -2230,7 +2230,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstTimeUnit final : public AstNodeExpr { VTimescale m_timeunit; // Parent module time unit @@ -2246,7 +2246,7 @@ public: string emitSimpleOperator() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } VTimescale timeunit() const { return m_timeunit; } void timeunit(const VTimescale& flag) { m_timeunit = flag; } }; @@ -2268,7 +2268,7 @@ public: bool isSubstOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstUnbounded final : public AstNodeExpr { // A $ in the parser, used for unbounded and queues @@ -2320,7 +2320,7 @@ public: bool isPredictOptimizable() const override { return false; } bool isPure() override { return !outp(); } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstWith final : public AstNodeExpr { // Used as argument to method, then to AstCMethodHard @@ -2341,7 +2341,7 @@ public: this->addExprp(exprp); } ASTGEN_MEMBERS_AstWith; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } const char* broken() const override { BROKEN_RTN(!indexArgRefp()); // varp needed to know lambda's arg dtype BROKEN_RTN(!valueArgRefp()); // varp needed to know lambda's arg dtype @@ -2366,7 +2366,7 @@ public: this->addExprsp(exprsp); } ASTGEN_MEMBERS_AstWithParse; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } string emitVerilog() override { V3ERROR_NA_RETURN(""); } string emitC() override { V3ERROR_NA_RETURN(""); } @@ -4158,7 +4158,7 @@ public: bool sizeMattersRhs() const override { return false; } bool isGateOptimizable() const override { return true; } // esp for V3Const::ifSameAssign bool isPredictOptimizable() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } // Special operators // Return base var (or const) nodep dereferences @@ -4194,7 +4194,7 @@ public: bool isGateOptimizable() const override { return false; } // AssocSel creates on miss bool isPredictOptimizable() const override { return false; } bool isPure() override { return false; } // AssocSel creates on miss - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } }; class AstWildcardSel final : public AstNodeSel { @@ -4226,7 +4226,7 @@ public: bool sizeMattersRhs() const override { return false; } bool isGateOptimizable() const override { return true; } // esp for V3Const::ifSameAssign bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } }; class AstWordSel final : public AstNodeSel { @@ -4252,7 +4252,7 @@ public: bool cleanRhs() const override { return true; } bool sizeMattersLhs() const override { return false; } bool sizeMattersRhs() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; // === AstNodeStream === @@ -4402,7 +4402,7 @@ public: AstNew(FileLine* fl, AstNodeExpr* pinsp) : ASTGEN_SUPER_New(fl, "new", pinsp) {} ASTGEN_MEMBERS_AstNew; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int instrCount() const override { return widthInstrs(); } }; class AstTaskRef final : public AstNodeFTaskRef { @@ -4511,7 +4511,7 @@ public: string emitVerilog() override { return "%f$inferred_disable"; } string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstTime final : public AstNodeTermop { VTimescale m_timeunit; // Parent module time unit @@ -4528,7 +4528,7 @@ public: bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_TIME; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; VTimescale timeunit() const { return m_timeunit; } @@ -4549,7 +4549,7 @@ public: bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_TIME; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; VTimescale timeunit() const { return m_timeunit; } @@ -4719,7 +4719,7 @@ public: bool sizeMattersLhs() const override { return false; } bool sizeMattersRhs() const override { return false; } bool sizeMattersThs() const override { return false; } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } int instrCount() const override { return widthInstrs() * (VN_CAST(lsbp(), Const) ? 3 : 10); } int widthConst() const { return VN_AS(widthp(), Const)->toSInt(); } int lsbConst() const { return VN_AS(lsbp(), Const)->toSInt(); } @@ -4756,7 +4756,7 @@ public: bool sizeMattersLhs() const override { return false; } bool sizeMattersRhs() const override { return false; } bool sizeMattersThs() const override { return false; } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } int instrCount() const override { return 10; } // Removed before matters // For widthConst()/loConst etc, see declRange().elements() and other VNumRange methods VNumRange& declRange() VL_MT_STABLE { return m_declRange; } @@ -4940,7 +4940,7 @@ public: bool cleanOut() const override { return true; } bool cleanLhs() const override { return true; } bool sizeMattersLhs() const override { return false; } // Special cased in V3Cast - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return size() == VN_DBG_AS(samep, CCast)->size(); } void dump(std::ostream& str = std::cout) const override; @@ -5006,7 +5006,7 @@ public: bool cleanOut() const override { return true; } bool cleanLhs() const override { return true; } bool sizeMattersLhs() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstExtend final : public AstNodeUniop { // Expand a value into a wider entity by 0 extension. Width is implied from nodep->width() @@ -5269,7 +5269,7 @@ public: bool cleanOut() const override { return true; } bool cleanLhs() const override { return true; } bool sizeMattersLhs() const override { return false; } - bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } + bool sameNode(const AstNode* samep) const override { return fileline() == samep->fileline(); } }; class AstOneHot final : public AstNodeUniop { // True if only single bit set in vector @@ -5718,8 +5718,8 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; const char* broken() const override; - bool same(const AstNode* samep) const override; - inline bool same(const AstVarRef* samep) const; + bool sameNode(const AstNode* samep) const override; + inline bool sameNode(const AstVarRef* samep) const; inline bool sameNoLvalue(AstVarRef* samep) const; int instrCount() const override; string emitVerilog() override { V3ERROR_NA_RETURN(""); } @@ -5751,7 +5751,7 @@ public: string emitC() override { V3ERROR_NA_RETURN(""); } bool cleanOut() const override { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstVarXRef* asamep = VN_DBG_AS(samep, VarXRef); return (selfPointer() == asamep->selfPointer() && varp() == asamep->varp() && name() == asamep->name() && dotted() == asamep->dotted()); diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index c38cc4773..c171f5098 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -214,7 +214,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; string name() const override VL_MT_STABLE { return m_name; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstNodeModule VL_NOT_FINAL : public AstNode { // A module, package, program or interface declaration; @@ -375,7 +375,7 @@ public: bool hasDType() const override VL_MT_SAFE { return true; } virtual bool cleanRhs() const { return true; } int instrCount() const override { return widthInstrs(); } - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } string verilogKwd() const override { return "="; } bool isTimingControl() const override { return timingControlp(); } virtual bool brokeLhsMustBeLvalue() const = 0; @@ -418,7 +418,7 @@ public: } ASTGEN_MEMBERS_AstNodeCoverOrAssert; string name() const override VL_MT_STABLE { return m_name; } // * = Var name - bool same(const AstNode* samep) const override { return samep->name() == name(); } + bool sameNode(const AstNode* samep) const override { return samep->name() == name(); } void name(const string& name) override { m_name = name; } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; @@ -450,7 +450,7 @@ public: ASTGEN_MEMBERS_AstNodeFor; bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstNodeForeach VL_NOT_FINAL : public AstNodeStmt { // @astgen op1 := arrayp : AstNode @@ -464,7 +464,7 @@ public: ASTGEN_MEMBERS_AstNodeForeach; bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstNodeIf VL_NOT_FINAL : public AstNodeStmt { @@ -487,7 +487,7 @@ public: bool isGateOptimizable() const override { return false; } bool isGateDedupable() const override { return true; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } void branchPred(VBranchPred flag) { m_branchPred = flag; } VBranchPred branchPred() const { return m_branchPred; } void isBoundsCheck(bool flag) { m_isBoundsCheck = flag; } @@ -519,7 +519,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return isHex() == VN_DBG_AS(samep, NodeReadWriteMem)->isHex(); } bool isHex() const { return m_isHex; } @@ -540,7 +540,7 @@ public: ASTGEN_MEMBERS_AstNodeText; void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstNodeText* asamep = VN_DBG_AS(samep, NodeText); return text() == asamep->text(); } @@ -677,7 +677,7 @@ public: bool maybePointedTo() const override VL_MT_SAFE { return true; } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstCFunc* const asamep = VN_DBG_AS(samep, CFunc); return ((isTrace() == asamep->isTrace()) && (rtnTypeVoid() == asamep->rtnTypeVoid()) && (argTypes() == asamep->argTypes()) && isLoose() == asamep->isLoose() @@ -1037,7 +1037,7 @@ public: bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } bool maybePointedTo() const override VL_MT_SAFE { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } void isKwdPure(bool flag) { m_isKwdPure = flag; } bool isKwdPure() const { return m_isKwdPure; } void isStatic(bool flag) { m_isStatic = flag; } @@ -1056,7 +1056,7 @@ public: ASTGEN_MEMBERS_AstConstraintBefore; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstDefParam final : public AstNode { // A defparam assignment @@ -1073,7 +1073,7 @@ public: } string name() const override VL_MT_STABLE { return m_name; } // * = Scope name ASTGEN_MEMBERS_AstDefParam; - bool same(const AstNode*) const override { return true; } + bool sameNode(const AstNode*) const override { return true; } string path() const { return m_path; } }; class AstDefaultDisable final : public AstNode { @@ -1121,7 +1121,7 @@ public: bool isPure() override { return false; } // SPECIAL: $display has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: $display makes output bool isUnlikely() const override { return true; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return displayType() == VN_DBG_AS(samep, ElabDisplay)->displayType(); } int instrCount() const override { return INSTR_COUNT_PLI; } @@ -1134,7 +1134,7 @@ public: explicit AstEmpty(FileLine* fl) : ASTGEN_SUPER_Empty(fl) {} ASTGEN_MEMBERS_AstEmpty; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstExecGraph final : public AstNode { // For parallel execution, this node contains a dependency graph. Each @@ -1482,7 +1482,7 @@ public: ASTGEN_MEMBERS_AstPragma; VPragmaType pragType() const { return m_pragType; } // *=type of the pragma bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return pragType() == VN_DBG_AS(samep, Pragma)->pragType(); } }; @@ -1517,7 +1517,7 @@ public: this->lhsp(lhsp); } ASTGEN_MEMBERS_AstPull; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return direction() == VN_DBG_AS(samep, Pull)->direction(); } uint32_t direction() const { return (uint32_t)m_direction; } @@ -1555,7 +1555,7 @@ public: void name(const string& name) override { m_name = name; } void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; string nameDotless() const; AstNodeModule* modp() const { return m_modp; } // @@ -1602,7 +1602,7 @@ public: ASTGEN_MEMBERS_AstSenItem; void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return edgeType() == VN_DBG_AS(samep, SenItem)->edgeType(); } VEdgeType edgeType() const { return m_edgeType; } @@ -1955,7 +1955,7 @@ public: ASTGEN_MEMBERS_AstVar; void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; string name() const override VL_MT_STABLE { return m_name; } // * = Var name bool hasDType() const override VL_MT_SAFE { return true; } bool maybePointedTo() const override VL_MT_SAFE { return true; } @@ -2211,7 +2211,7 @@ public: string name() const override VL_MT_STABLE { return scopep()->name() + "->" + varp()->name(); } void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; - bool same(const AstNode* samep) const override; + bool sameNode(const AstNode* samep) const override; bool hasDType() const override VL_MT_SAFE { return true; } AstVar* varp() const VL_MT_STABLE { return m_varp; } // [After Link] Pointer to variable AstScope* scopep() const VL_MT_STABLE { return m_scopep; } // Pointer to scope it's under @@ -2598,7 +2598,7 @@ public: ASTGEN_MEMBERS_AstBracketRange; virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitVerilog() { V3ERROR_NA_RETURN(""); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } // Will be removed in V3Width, which relies on this // being a child not a dtype pointed node bool maybePointedTo() const override VL_MT_SAFE { return false; } @@ -2633,7 +2633,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; virtual string emitC() { V3ERROR_NA_RETURN(""); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstUnsizedRange final : public AstNodeRange { // Unsized range specification, for open arrays @@ -2643,7 +2643,7 @@ public: ASTGEN_MEMBERS_AstUnsizedRange; virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitVerilog() { return "[]"; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstWildcardRange final : public AstNodeRange { // Wildcard range specification, for wildcard index type associative arrays @@ -2653,7 +2653,7 @@ public: ASTGEN_MEMBERS_AstWildcardRange; virtual string emitC() { V3ERROR_NA_RETURN(""); } virtual string emitVerilog() { return "[*]"; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; // === AstNodeStmt === @@ -2669,7 +2669,7 @@ public: addStmtsp(stmtsp); } ASTGEN_MEMBERS_AstAlwaysPublic; - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } // Special accessors bool isJustOneBodyStmt() const { return stmtsp() && !stmtsp()->nextp(); } bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } @@ -2726,7 +2726,7 @@ public: ASTGEN_MEMBERS_AstCReset; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstCReturn final : public AstNodeStmt { // C++ return from a function @@ -2738,7 +2738,7 @@ public: } ASTGEN_MEMBERS_AstCReturn; int instrCount() const override { return widthInstrs(); } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstCStmt final : public AstNodeStmt { // Emit C statement @@ -2752,7 +2752,7 @@ public: ASTGEN_MEMBERS_AstCStmt; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstComment final : public AstNodeStmt { // Some comment to put into the output stream @@ -2765,7 +2765,7 @@ public: , m_showAt{showAt} {} ASTGEN_MEMBERS_AstComment; string name() const override VL_MT_STABLE { return m_name; } // * = Text - bool same(const AstNode* samep) const override { return true; } // Ignore name in comments + bool sameNode(const AstNode* samep) const override { return true; } // Ignore name in comments virtual bool showAt() const { return m_showAt; } }; class AstConstraintExpr final : public AstNodeStmt { @@ -2783,7 +2783,7 @@ public: void dumpJson(std::ostream& str) const override; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool isDisableSoft() const { return m_isDisableSoft; } void isDisableSoft(bool flag) { m_isDisableSoft = flag; } bool isSoft() const { return m_isSoft; } @@ -2800,7 +2800,7 @@ public: ASTGEN_MEMBERS_AstConstraintUnique; bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return false; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstContinue final : public AstNodeStmt { public: @@ -2852,7 +2852,7 @@ public: const string& hier() const { return m_hier; } void hier(const string& flag) { m_hier = flag; } void comment(const string& flag) { m_text = flag; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { const AstCoverDecl* const asamep = VN_DBG_AS(samep, CoverDecl); return (fileline() == asamep->fileline() && linescov() == asamep->linescov() && hier() == asamep->hier() && comment() == asamep->comment()); @@ -2876,7 +2876,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; int instrCount() const override { return 1 + 2 * INSTR_COUNT_LD; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return declp() == VN_DBG_AS(samep, CoverInc)->declp(); } bool isGateOptimizable() const override { return false; } @@ -2900,7 +2900,7 @@ public: } ASTGEN_MEMBERS_AstCoverToggle; int instrCount() const override { return 3 + INSTR_COUNT_BRANCH + INSTR_COUNT_LD; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool isGateOptimizable() const override { return false; } bool isPredictOptimizable() const override { return true; } bool isOutputter() override { @@ -2925,7 +2925,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; bool isTimingControl() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } void timeunit(const VTimescale& flag) { m_timeunit = flag; } VTimescale timeunit() const { return m_timeunit; } bool isCycleDelay() const { return m_isCycle; } @@ -2987,7 +2987,7 @@ public: bool isPure() override { return false; } // SPECIAL: $display has 'visual' ordering bool isOutputter() override { return true; } // SPECIAL: $display makes output bool isUnlikely() const override { return true; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return displayType() == VN_DBG_AS(samep, Display)->displayType(); } int instrCount() const override { return INSTR_COUNT_PLI; } @@ -3008,7 +3008,7 @@ public: ASTGEN_MEMBERS_AstDoWhile; bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } // Stop statement searchback here bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; @@ -3030,7 +3030,7 @@ public: bool isPredictOptimizable() const override { return false; } bool isPure() override { return false; } virtual bool cleanOut() const { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } VDumpCtlType ctlType() const { return m_ctlType; } }; class AstEventControl final : public AstNodeStmt { @@ -3063,7 +3063,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFFlush final : public AstNodeStmt { // Parents: stmtlist @@ -3080,7 +3080,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstFinish final : public AstNodeStmt { public: @@ -3093,7 +3093,7 @@ public: bool isOutputter() override { return true; } // SPECIAL: $display makes output bool isUnlikely() const override { return true; } int instrCount() const override { return 0; } // Rarely executes - bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } + bool sameNode(const AstNode* samep) const override { return fileline() == samep->fileline(); } }; class AstFireEvent final : public AstNodeStmt { // '-> _' and '->> _' event trigger statements @@ -3128,7 +3128,7 @@ public: const char* broken() const override; int instrCount() const override { return 0; } bool maybePointedTo() const override VL_MT_SAFE { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } int labelNum() const { return m_labelNum; } void labelNum(int flag) { m_labelNum = flag; } AstJumpLabel* labelp() const { return m_labelp; } @@ -3154,7 +3154,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return labelp() == VN_DBG_AS(samep, JumpGo)->labelp(); } bool isGateOptimizable() const override { return false; } @@ -3182,7 +3182,7 @@ public: void dump(std::ostream& str) const override; void dumpJson(std::ostream& str) const override; int instrCount() const override { return 0; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return blockp() == VN_DBG_AS(samep, JumpLabel)->blockp(); } AstJumpBlock* blockp() const { return m_blockp; } @@ -3201,7 +3201,7 @@ public: bool isPure() override { return false; } // Though deleted before opt bool isOutputter() override { return true; } // Though deleted before opt int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return m_off == VN_DBG_AS(samep, MonitorOff)->m_off; } bool off() const { return m_off; } @@ -3259,7 +3259,7 @@ public: ASTGEN_MEMBERS_AstRepeat; bool isGateOptimizable() const override { return false; } // Not relevant - converted to FOR int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } }; class AstReturn final : public AstNodeStmt { @@ -3303,7 +3303,7 @@ public: bool isOutputter() override { return false; } virtual bool cleanOut() const { return false; } int instrCount() const override { return INSTR_COUNT_PLI; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstStackTraceT final : public AstNodeStmt { // $stacktrace used as task @@ -3317,7 +3317,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstStmtExpr final : public AstNodeStmt { // Expression in statement position @@ -3345,7 +3345,7 @@ public: bool isOutputter() override { return true; } // SPECIAL: $display makes output bool isUnlikely() const override { return true; } int instrCount() const override { return 0; } // Rarely executes - bool same(const AstNode* samep) const override { return fileline() == samep->fileline(); } + bool sameNode(const AstNode* samep) const override { return fileline() == samep->fileline(); } string emitVerilog() const { return m_isFatal ? "$fatal" : "$stop"; } bool isFatal() const { return m_isFatal; } }; @@ -3365,7 +3365,7 @@ public: bool isPure() override { return true; } bool isOutputter() override { return false; } int instrCount() const override { return 0; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstSystemT final : public AstNodeStmt { // $system used as task @@ -3382,7 +3382,7 @@ public: bool isPure() override { return false; } bool isOutputter() override { return true; } bool isUnlikely() const override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstTimeFormat final : public AstNodeStmt { // Parents: stmtlist @@ -3440,7 +3440,7 @@ public: string name() const override VL_MT_STABLE { return m_showname; } bool maybePointedTo() const override VL_MT_SAFE { return true; } bool hasDType() const override VL_MT_SAFE { return true; } - bool same(const AstNode* samep) const override { return false; } + bool sameNode(const AstNode* samep) const override { return false; } string showname() const { return m_showname; } // * = Var name // Details on what we're tracing uint32_t code() const { return m_code; } @@ -3481,7 +3481,7 @@ public: void dumpJson(std::ostream& str) const override; int instrCount() const override { return 10 + 2 * INSTR_COUNT_LD; } bool hasDType() const override VL_MT_SAFE { return true; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return declp() == VN_DBG_AS(samep, TraceInc)->declp(); } bool isGateOptimizable() const override { return false; } @@ -3497,7 +3497,7 @@ public: explicit AstTracePopPrefix(FileLine* fl) : ASTGEN_SUPER_TracePopPrefix(fl) {} ASTGEN_MEMBERS_AstTracePopPrefix; - bool same(const AstNode* samep) const override { return false; } + bool sameNode(const AstNode* samep) const override { return false; } }; class AstTracePushPrefix final : public AstNodeStmt { const string m_prefix; // Prefix to add to signal names @@ -3508,7 +3508,7 @@ public: , m_prefix{prefix} , m_prefixType{prefixType} {} ASTGEN_MEMBERS_AstTracePushPrefix; - bool same(const AstNode* samep) const override { return false; } + bool sameNode(const AstNode* samep) const override { return false; } string prefix() const { return m_prefix; } VTracePrefixType prefixType() const { return m_prefixType; } }; @@ -3525,7 +3525,7 @@ public: bool isPredictOptimizable() const override { return false; } bool isPure() override { return false; } bool isOutputter() override { return true; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } }; class AstWait final : public AstNodeStmt { // @astgen op1 := condp : AstNodeExpr @@ -3565,7 +3565,7 @@ public: void dump(std::ostream& str) const override; bool isGateOptimizable() const override { return false; } int instrCount() const override { return INSTR_COUNT_BRANCH; } - bool same(const AstNode* /*samep*/) const override { return true; } + bool sameNode(const AstNode* /*samep*/) const override { return true; } // Stop statement searchback here void addNextStmt(AstNode* newp, AstNode* belowp) override; bool isFirstInMyListOfStatements(AstNode* n) const override { return n == stmtsp(); } @@ -3697,7 +3697,7 @@ public: , m_casex{casex} {} ASTGEN_MEMBERS_AstCase; string verilogKwd() const override { return casez() ? "casez" : casex() ? "casex" : "case"; } - bool same(const AstNode* samep) const override { + bool sameNode(const AstNode* samep) const override { return m_casex == VN_DBG_AS(samep, Case)->m_casex; } bool casex() const { return m_casex == VCaseType::CT_CASEX; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 6137f0c74..6d3872f5c 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -258,7 +258,7 @@ int AstBasicDType::widthTotalBytes() const { } } -bool AstBasicDType::same(const AstNode* samep) const { +bool AstBasicDType::sameNode(const AstNode* samep) const { const AstBasicDType* const sp = VN_DBG_AS(samep, BasicDType); if (!(m == sp->m) || numeric() != sp->numeric()) return false; if (!rangep() && !sp->rangep()) return true; @@ -1912,10 +1912,10 @@ AstMemberSel::AstMemberSel(FileLine* fl, AstNodeExpr* fromp, AstVar* varp) this->varp(varp); dtypep(varp->dtypep()); } -bool AstMemberSel::same(const AstNode* samep) const { +bool AstMemberSel::sameNode(const AstNode* samep) const { const AstMemberSel* const sp = VN_DBG_AS(samep, MemberSel); return sp != nullptr && access() == sp->access() && fromp()->isSame(sp->fromp()) - && name() == sp->name() && varp()->same(sp->varp()); + && name() == sp->name() && varp()->sameNode(sp->varp()); } void AstMemberSel::dump(std::ostream& str) const { @@ -2334,7 +2334,7 @@ void AstWildcardArrayDType::dumpSmall(std::ostream& str) const { this->AstNodeDType::dumpSmall(str); str << "[*]"; } -bool AstWildcardArrayDType::same(const AstNode* samep) const { +bool AstWildcardArrayDType::sameNode(const AstNode* samep) const { const AstWildcardArrayDType* const asamep = VN_DBG_AS(samep, WildcardArrayDType); if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); @@ -2353,7 +2353,7 @@ void AstUnsizedArrayDType::dumpSmall(std::ostream& str) const { this->AstNodeDType::dumpSmall(str); str << "[]"; } -bool AstUnsizedArrayDType::same(const AstNode* samep) const { +bool AstUnsizedArrayDType::sameNode(const AstNode* samep) const { const AstUnsizedArrayDType* const asamep = VN_DBG_AS(samep, UnsizedArrayDType); if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); @@ -2391,9 +2391,9 @@ void AstVarScope::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, isTrace); dumpJsonGen(str); } -bool AstVarScope::same(const AstNode* samep) const { +bool AstVarScope::sameNode(const AstNode* samep) const { const AstVarScope* const asamep = VN_DBG_AS(samep, VarScope); - return varp()->same(asamep->varp()) && scopep()->same(asamep->scopep()); + return varp()->sameNode(asamep->varp()) && scopep()->sameNode(asamep->scopep()); } void AstNodeVarRef::dump(std::ostream& str) const { this->AstNodeExpr::dump(str); @@ -2436,7 +2436,7 @@ const char* AstVarRef::broken() const { BROKEN_RTN(!varp()); return nullptr; } -bool AstVarRef::same(const AstNode* samep) const { return same(VN_DBG_AS(samep, VarRef)); } +bool AstVarRef::sameNode(const AstNode* samep) const { return sameNode(VN_DBG_AS(samep, VarRef)); } int AstVarRef::instrCount() const { // Account for the target of hard-coded method calls as just an address computation if (const AstCMethodHard* const callp = VN_CAST(backp(), CMethodHard)) { @@ -2502,7 +2502,7 @@ void AstVar::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, attrSFormat); dumpJsonGen(str); } -bool AstVar::same(const AstNode* samep) const { +bool AstVar::sameNode(const AstNode* samep) const { const AstVar* const asamep = VN_DBG_AS(samep, Var); return name() == asamep->name() && varType() == asamep->varType(); } @@ -2520,7 +2520,7 @@ void AstScope::dump(std::ostream& str) const { str << " [modp=" << nodeAddr(modp()) << "]"; } void AstScope::dumpJson(std::ostream& str) const { dumpJsonGen(str); } -bool AstScope::same(const AstNode* samep) const { +bool AstScope::sameNode(const AstNode* samep) const { const AstScope* const asamep = VN_DBG_AS(samep, Scope); return name() == asamep->name() && ((!aboveScopep() && !asamep->aboveScopep()) diff --git a/src/V3Const.cpp b/src/V3Const.cpp index ec8107bc6..f25116282 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -227,7 +227,7 @@ class ConstBitOpTreeVisitor final : public VNVisitorConst { return m_knownResult == 1; } const AstVarRef* refp() const { return m_refp; } - bool sameVarAs(const AstNodeVarRef* otherp) const { return m_refp->same(otherp); } + bool sameVarAs(const AstNodeVarRef* otherp) const { return m_refp->sameNode(otherp); } void setPolarity(bool compBit, int bit) { // Ignore if already determined a known reduction if (m_knownResult >= 0) return; diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 371997963..1ddac0799 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -1190,7 +1190,7 @@ class GateMergeAssignments final { AstSel* merge(AstSel* prevSelp, AstSel* currSelp) { const AstVarRef* const pRefp = VN_CAST(prevSelp->fromp(), VarRef); AstVarRef* const cRefp = VN_CAST(currSelp->fromp(), VarRef); - if (!pRefp || !cRefp || !cRefp->same(pRefp)) return nullptr; // not the same var + if (!pRefp || !cRefp || !cRefp->sameNode(pRefp)) return nullptr; // not the same var const AstConst* const pstart = VN_CAST(prevSelp->lsbp(), Const); const AstConst* const pwidth = VN_CAST(prevSelp->widthp(), Const); From 7efa0fc82a3ed444d6753952c4cfddc1a1093732 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 08:10:51 -0500 Subject: [PATCH 106/171] Internals: Rewrite skipRefp to avoid recursion and fix const-ness. No functional change intended. --- src/V3AstNodeDType.h | 139 ++++++----------------------------------- src/V3AstNodes.cpp | 21 ++++++- src/V3Class.cpp | 4 +- src/V3EmitCHeaders.cpp | 2 +- src/V3HierBlock.cpp | 2 +- src/V3Param.cpp | 6 +- src/V3Width.cpp | 2 +- 7 files changed, 47 insertions(+), 129 deletions(-) diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index 3e419d09f..ee588bd33 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -48,6 +48,10 @@ protected: AstNodeDType(VNType t, FileLine* fl) : AstNode{t, fl} {} +private: + // METHODS + const AstNodeDType* skipRefIterp(bool skipConst, bool skipEnum) const VL_MT_STABLE; + public: ASTGEN_MEMBERS_AstNodeDType; // ACCESSORS @@ -65,11 +69,23 @@ public: // (Slow) recurse down to find basic data type virtual AstBasicDType* basicp() const VL_MT_STABLE = 0; // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|ConstDType|EnumDType to other type - virtual AstNodeDType* skipRefp() const VL_MT_STABLE = 0; + const AstNodeDType* skipRefp() const VL_MT_STABLE { return skipRefIterp(true, true); } + AstNodeDType* skipRefp() VL_MT_STABLE { + return const_cast( + static_cast(this)->skipRefIterp(true, true)); + } // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|EnumDType to ConstDType - virtual AstNodeDType* skipRefToConstp() const = 0; + const AstNodeDType* skipRefToConstp() const { return skipRefIterp(false, true); } + AstNodeDType* skipRefToConstp() { + return const_cast( + static_cast(this)->skipRefIterp(false, true)); + } // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType|ConstDType to EnumDType - virtual AstNodeDType* skipRefToEnump() const = 0; + const AstNodeDType* skipRefToEnump() const { return skipRefIterp(true, false); } + AstNodeDType* skipRefToEnump() { + return const_cast( + static_cast(this)->skipRefIterp(true, false)); + } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthAlignBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... @@ -177,9 +193,6 @@ public: AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return elementsConst() * subDTypep()->widthTotalBytes(); @@ -232,9 +245,6 @@ public: : VN_AS(findBitRangeDType(VNumRange{width() - 1, 0}, width(), numeric()), BasicDType)); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) int widthAlignBytes() const override; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... @@ -342,9 +352,6 @@ public: void keyDTypep(AstNodeDType* nodep) { m_keyDTypep = nodep; } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } bool isCompound() const override { return true; } @@ -412,9 +419,6 @@ public: } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return (AstBasicDType*)this; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) int widthAlignBytes() const override; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... @@ -489,9 +493,6 @@ public: // being a child not a dtype pointed node bool maybePointedTo() const override VL_MT_SAFE { return false; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { V3ERROR_NA_RETURN(0); } int widthTotalBytes() const override { V3ERROR_NA_RETURN(0); } bool isCompound() const override { return true; } @@ -517,9 +518,6 @@ public: string prettyDTypeName(bool) const override { return m_name; } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 8; } // Assume int widthTotalBytes() const override { return 8; } // Assume bool isCompound() const override { return true; } @@ -564,9 +562,6 @@ public: string prettyDTypeName(bool full) const override; string name() const override VL_MT_STABLE; AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } AstNodeDType* virtRefDTypep() const override { return nullptr; } @@ -614,9 +609,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } bool isCompound() const override { @@ -640,12 +632,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override {} bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } bool isCompound() const override { return false; } @@ -693,9 +679,6 @@ public: // op1 = Range of variable AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); } int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); } string name() const override VL_MT_STABLE { return m_name; } @@ -746,9 +729,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } bool isCompound() const override { return true; } @@ -770,12 +750,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override {} bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } bool isCompound() const override { return false; } @@ -832,10 +806,6 @@ public: string prettyDTypeName(bool full) const override; // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); } - AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } size_t itemCount() const { @@ -890,9 +860,6 @@ public: void dumpJson(std::ostream& str = std::cout) const override; void dumpSmall(std::ostream& str) const override; AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } bool similarDType(const AstNodeDType* samep) const override { return this == samep; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } @@ -955,7 +922,7 @@ public: bool hasDType() const override VL_MT_SAFE { return true; } bool maybePointedTo() const override VL_MT_SAFE { return true; } AstNodeDType* getChildDTypep() const override { return childDTypep(); } - AstNodeUOrStructDType* getChildStructp() const; + AstNodeUOrStructDType* getChildStructp(); AstNodeDType* subDTypep() const override VL_MT_STABLE { return m_refDTypep ? m_refDTypep : childDTypep(); } @@ -969,9 +936,6 @@ public: AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); } - AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); } - AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... @@ -1004,9 +968,6 @@ public: bool partial() const { return m_partial; } bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 24; } bool isCompound() const override { return true; } @@ -1034,9 +995,6 @@ public: return dtypep() ? dtypep() : childDTypep(); } AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return subDTypep()->skipRefp(); } - AstNodeDType* skipRefToConstp() const override { return subDTypep()->skipRefToConstp(); } - AstNodeDType* skipRefToEnump() const override { return subDTypep()->skipRefToEnump(); } bool similarDType(const AstNodeDType* samep) const override { if (type() != samep->type()) return false; const AstParamTypeDType* const sp = VN_DBG_AS(samep, ParamTypeDType); @@ -1069,11 +1027,6 @@ public: // METHODS bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } bool isCompound() const override { @@ -1129,12 +1082,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } bool isCompound() const override { return true; } @@ -1188,31 +1135,6 @@ public: return subDTypep() ? subDTypep()->basicp() : nullptr; } AstNodeDType* subDTypep() const override VL_MT_STABLE; - AstNodeDType* skipRefp() const override VL_MT_STABLE { - // Skip past both the Ref and the Typedef - if (subDTypep()) { - return subDTypep()->skipRefp(); - } else { - v3fatalSrc("Typedef not linked"); - return nullptr; - } - } - AstNodeDType* skipRefToConstp() const override { - if (subDTypep()) { - return subDTypep()->skipRefToConstp(); - } else { - v3fatalSrc("Typedef not linked"); - return nullptr; - } - } - AstNodeDType* skipRefToEnump() const override { - if (subDTypep()) { - return subDTypep()->skipRefToEnump(); - } else { - v3fatalSrc("Typedef not linked"); - return nullptr; - } - } int widthAlignBytes() const override { return dtypeSkipRefp()->widthAlignBytes(); } int widthTotalBytes() const override { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) override { m_name = flag; } @@ -1267,9 +1189,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return sizeof(std::map); } int widthTotalBytes() const override { return sizeof(std::map); } bool isCompound() const override { return true; } @@ -1292,12 +1211,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override {} bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } bool isCompound() const override { return false; } @@ -1336,9 +1249,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return subDTypep()->widthAlignBytes(); } int widthTotalBytes() const override { return subDTypep()->widthTotalBytes(); } bool isCompound() const override { return true; } @@ -1360,12 +1270,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override {} bool similarDType(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - // cppcheck-suppress csyleCast - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } bool isCompound() const override { return false; } @@ -1399,9 +1303,6 @@ public: void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } // METHODS AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - AstNodeDType* skipRefp() const override VL_MT_STABLE { return (AstNodeDType*)this; } - AstNodeDType* skipRefToConstp() const override { return (AstNodeDType*)this; } - AstNodeDType* skipRefToEnump() const override { return (AstNodeDType*)this; } int widthAlignBytes() const override { return sizeof(std::map); } int widthTotalBytes() const override { return sizeof(std::map); } bool isCompound() const override { return true; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 6d3872f5c..4ada5e738 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -783,6 +783,25 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) { return nullptr; } +const AstNodeDType* AstNodeDType::skipRefIterp(bool skipConst, bool skipEnum) const VL_MT_STABLE { + const AstNodeDType* nodep = this; + while (true) { + if (VL_UNLIKELY(VN_IS(nodep, MemberDType) || VN_IS(nodep, ParamTypeDType) + || VN_IS(nodep, RefDType) // + || (VN_IS(nodep, ConstDType) && skipConst) // + || (VN_IS(nodep, EnumDType) && skipEnum))) { + if (const AstNodeDType* subp = nodep->subDTypep()) { + nodep = subp; + continue; + } else { + v3fatalSrc("Typedef not linked"); + return nullptr; + } + } + return nodep; + } +} + bool AstNodeDType::isFourstate() const { return basicp() && basicp()->isFourstate(); } class AstNodeDType::CTypeRecursed final { @@ -1896,7 +1915,7 @@ void AstMemberDType::dumpSmall(std::ostream& str) const { this->AstNodeDType::dumpSmall(str); str << "member"; } -AstNodeUOrStructDType* AstMemberDType::getChildStructp() const { +AstNodeUOrStructDType* AstMemberDType::getChildStructp() { AstNodeDType* subdtp = skipRefp(); while (AstNodeArrayDType* const asubdtp = VN_CAST(subdtp, NodeArrayDType)) { subdtp = asubdtp->subDTypep(); diff --git a/src/V3Class.cpp b/src/V3Class.cpp index 9e82be6ea..be16c81cd 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -208,7 +208,7 @@ class ClassVisitor final : public VNVisitor { m_names.get(dtypep->name() + (VN_IS(dtypep, UnionDType) ? "__union" : "__struct"))); if (dtypep->packed()) m_strDtypeps.insert(dtypep); - for (const AstMemberDType* itemp = dtypep->membersp(); itemp; + for (AstMemberDType* itemp = dtypep->membersp(); itemp; itemp = VN_AS(itemp->nextp(), MemberDType)) { AstNodeUOrStructDType* const subp = itemp->getChildStructp(); // Recurse only into anonymous structs inside this definition, @@ -271,7 +271,7 @@ public: AstNodeUOrStructDType* const dtypep = m_pubStrDtypeps.front(); m_pubStrDtypeps.pop(); if (pubStrDtypeps.insert(dtypep).second) { - for (const AstMemberDType* itemp = dtypep->membersp(); itemp; + for (AstMemberDType* itemp = dtypep->membersp(); itemp; itemp = VN_AS(itemp->nextp(), MemberDType)) { if (AstNodeUOrStructDType* const subp = itemp->getChildStructp()) m_pubStrDtypeps.push(subp); diff --git a/src/V3EmitCHeaders.cpp b/src/V3EmitCHeaders.cpp index 839dc00ca..97268d140 100644 --- a/src/V3EmitCHeaders.cpp +++ b/src/V3EmitCHeaders.cpp @@ -223,7 +223,7 @@ class EmitCHeader final : public EmitCConstInit { std::set& emitted) { if (emitted.count(sdtypep) > 0) return; emitted.insert(sdtypep); - for (const AstMemberDType* itemp = sdtypep->membersp(); itemp; + for (AstMemberDType* itemp = sdtypep->membersp(); itemp; itemp = VN_AS(itemp->nextp(), MemberDType)) { AstNodeUOrStructDType* const subp = itemp->getChildStructp(); if (subp && (!subp->packed() || sdtypep->packed())) { diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index fb79927fe..853bc41eb 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -271,7 +271,7 @@ void V3HierBlock::writeParametersFile() const { const string moduleName = "Vhsh" + hash.digestSymbol(); const std::unique_ptr of{V3File::new_ofstream(typeParametersFilename())}; *of << "module " << moduleName << ";\n"; - for (const AstParamTypeDType* const gparam : m_params.gTypeParams()) { + for (AstParamTypeDType* const gparam : m_params.gTypeParams()) { AstTypedef* tdefp = new AstTypedef(new FileLine{FileLine::builtInFilename()}, gparam->name(), nullptr, VFlagChildDType{}, gparam->skipRefp()->cloneTreePure(true)); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index d427c4f58..f52246941 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -373,9 +373,7 @@ class ParamProcessor final { // TODO: This parameter value number lookup via a constructed key string is not // particularly robust for type parameters. We should really have a type // equivalence predicate function. - if (const AstRefDType* const refp = VN_CAST(nodep, RefDType)) { - nodep = refp->skipRefToEnump(); - } + if (AstRefDType* const refp = VN_CAST(nodep, RefDType)) { nodep = refp->skipRefToEnump(); } const string paramStr = paramValueString(nodep); // cppcheck-has-bug-suppress unreadVariable V3Hash hash = V3Hasher::uncachedHash(nodep) + paramStr; @@ -532,7 +530,7 @@ class ParamProcessor final { // nullptr means that the parameter is using some default value. params.emplace(varp->name(), constp); } - } else if (const AstParamTypeDType* const p = VN_CAST(stmtp, ParamTypeDType)) { + } else if (AstParamTypeDType* const p = VN_CAST(stmtp, ParamTypeDType)) { params.emplace(p->name(), p->skipRefp()); } } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 00a0d157c..f4a7c714a 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6868,7 +6868,7 @@ class WidthVisitor final : public VNVisitor { return false; } void checkClassAssign(AstNode* nodep, const char* side, AstNode* rhsp, - const AstNodeDType* const lhsDTypep) { + AstNodeDType* const lhsDTypep) { if (AstClassRefDType* const lhsClassRefp = VN_CAST(lhsDTypep->skipRefp(), ClassRefDType)) { UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type"); AstNodeDType* const rhsDtypep = rhsp->dtypep()->skipRefp(); From d750ffc129ca25027466641d69fd9483d5dbe864 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 08:51:32 -0500 Subject: [PATCH 107/171] Internals: Fix debug dump of deleted nodes. --- nodist/code_coverage.dat | 1 + src/V3Ast.cpp | 7 +++++++ src/V3Ast.h | 6 ++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/nodist/code_coverage.dat b/nodist/code_coverage.dat index 0fd860a54..81a9af018 100644 --- a/nodist/code_coverage.dat +++ b/nodist/code_coverage.dat @@ -40,6 +40,7 @@ remove_gcda_regexp(r'test_regress/.*/(Vt_|Vtop_).*\.gcda') # Exclude line entirely, also excludes from function and branch coverage exclude_line_regexp(r'\bv3fatalSrc\b') exclude_line_regexp(r'\bfatalSrc\b') +exclude_line_regexp(r'\bVL_DELETED\b') exclude_line_regexp(r'\bVL_UNCOVERABLE\b') exclude_line_regexp(r'\bVL_UNREACHABLE\b') exclude_line_regexp(r'\bVL_FATAL') diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 6ad2e4ef4..d0f41968f 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -1286,10 +1286,17 @@ void AstNode::dumpPtrs(std::ostream& os) const { void AstNode::dumpTree(std::ostream& os, const string& indent, int maxDepth) const { static int s_debugFileline = v3Global.opt.debugSrcLevel("fileline"); // --debugi-fileline 9 os << indent << " " << this << '\n'; + if (VN_DELETED(this)) return; if (debug() > 8) { os << indent << " "; dumpPtrs(os); } + if (VN_DELETED(op1p()) || VN_DELETED(op2p()) // LCOV_EXCL_START + || VN_DELETED(op3p()) || VN_DELETED(op4p())) { + os << indent << "1/2/3/4: %E-0x1/deleted! node " << cvtToHex(this) + << endl; // endl intentional to do flush + return; + } // LCOV_EXCL_STOP if (s_debugFileline >= 9) os << fileline()->warnContextSecondary(); if (maxDepth == 1) { if (op1p() || op2p() || op3p() || op4p()) os << indent << "1: ...(maxDepth)\n"; diff --git a/src/V3Ast.h b/src/V3Ast.h index 66466376b..4169c7dc2 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2992,8 +2992,10 @@ bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const Callable& p } inline std::ostream& operator<<(std::ostream& os, const AstNode* rhs) { - if (!rhs) { - os << "nullptr"; + if (!rhs) { // LCOV_EXCL_LINE + os << "nullptr"; // LCOV_EXCL_LINE + } else if (VN_DELETED(rhs)) { // LCOV_EXCL_LINE + os << "%E-0x1/deleted!"; // LCOV_EXCL_LINE } else { rhs->dump(os); } From 93090c56ee847b96822a7051725e84f4116ab954 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 09:20:02 -0500 Subject: [PATCH 108/171] Fix mis-aliasing of instances with mailbox parameter types (#5632 partial). --- Changes | 1 + src/V3AstNodeDType.h | 115 ++++++++++++++++-------------- src/V3AstNodes.cpp | 12 ++-- src/V3Hasher.cpp | 5 ++ src/V3Param.cpp | 14 ++-- test_regress/t/t_mailbox_array.py | 18 +++++ test_regress/t/t_mailbox_array.v | 26 +++++++ 7 files changed, 123 insertions(+), 68 deletions(-) create mode 100755 test_regress/t/t_mailbox_array.py create mode 100644 test_regress/t/t_mailbox_array.v diff --git a/Changes b/Changes index a0e6292c0..d8a560704 100644 --- a/Changes +++ b/Changes @@ -48,6 +48,7 @@ Verilator 5.031 devel * Fix NBAs to unpacked arrays of unpacked structs (#5603). [Geza Lore] * Fix array of struct member overwrites on member update (#5605) (#5618) (#5628). [sumpster] * Fix interface and struct pattern collision (#5639) (#5640). [Todd Strader] +* Fix mis-aliasing of instances with mailbox parameter types (#5632 partial). Verilator 5.030 2024-10-27 diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index ee588bd33..dc0220797 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -52,6 +52,10 @@ private: // METHODS const AstNodeDType* skipRefIterp(bool skipConst, bool skipEnum) const VL_MT_STABLE; +protected: + // METHODS + virtual bool similarDTypeNode(const AstNodeDType* samep) const = 0; + public: ASTGEN_MEMBERS_AstNodeDType; // ACCESSORS @@ -86,6 +90,12 @@ public: return const_cast( static_cast(this)->skipRefIterp(true, false)); } + // (Slow) Recurse over MemberDType|ParamTypeDType|RefDType to other type + const AstNodeDType* skipRefToNonRefp() const { return skipRefIterp(false, false); } + AstNodeDType* skipRefToNonRefp() { + return const_cast( + static_cast(this)->skipRefIterp(false, false)); + } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthAlignBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... @@ -99,8 +109,16 @@ public: virtual AstNodeDType* virtRefDType2p() const { return nullptr; } // Iff has second dtype, set as generic node function virtual void virtRefDType2p(AstNodeDType* nodep) {} - // Assignable equivalence. Call skipRefp() on this and samep before calling - virtual bool similarDType(const AstNodeDType* samep) const = 0; + // Assignable equivalence. Calls skipRefToNonRefp() during comparisons. + bool similarDType(const AstNodeDType* samep) const { + const AstNodeDType* nodep = this; + nodep = nodep->skipRefToNonRefp(); + samep = samep->skipRefToNonRefp(); + if (nodep == samep) return true; + if (nodep->type() != samep->type()) return false; + return nodep->similarDTypeNode(samep); + } + // Iff has a non-null subDTypep(), as generic node function virtual AstNodeDType* subDTypep() const VL_MT_STABLE { return nullptr; } virtual bool isFourstate() const; @@ -173,14 +191,13 @@ public: } bool sameNode(const AstNode* samep) const override { const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType); - return (hi() == asamep->hi() && subDTypep() == asamep->subDTypep() - && rangenp()->sameTree(asamep->rangenp())); + return hi() == asamep->hi() && rangenp()->sameTree(asamep->rangenp()) + && subDTypep() == asamep->subDTypep(); } // HashedDT doesn't recurse, so need to check children - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstNodeArrayDType* const asamep = VN_DBG_AS(samep, NodeArrayDType); - return (hi() == asamep->hi() && rangenp()->sameTree(asamep->rangenp()) - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp())); + return hi() == asamep->hi() && rangenp()->sameTree(asamep->rangenp()) + && subDTypep()->similarDType(asamep->subDTypep()); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { @@ -249,7 +266,7 @@ public: int widthAlignBytes() const override; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... int widthTotalBytes() const override; - bool similarDType(const AstNodeDType* samep) const override { + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; // We don't compare members, require exact equivalence } string name() const override VL_MT_STABLE { return m_name; } @@ -327,11 +344,10 @@ public: if (!asamep->keyDTypep()) return false; return (subDTypep() == asamep->subDTypep() && keyDTypep() == asamep->keyDTypep()); } - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstAssocArrayDType* const asamep = VN_DBG_AS(samep, AssocArrayDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()) + && asamep->keyDTypep() && keyDTypep()->similarDType(asamep->keyDTypep()); } string prettyDTypeName(bool full) const override; void dumpSmall(std::ostream& str) const override; @@ -400,9 +416,7 @@ public: void dumpJson(std::ostream& str) const override; // width/widthMin/numeric compared elsewhere bool sameNode(const AstNode* samep) const override; - bool similarDType(const AstNodeDType* samep) const override { - return type() == samep->type() && sameNode(samep); - } + bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } string name() const override VL_MT_STABLE { return m.m_keyword.ascii(); } string prettyDTypeName(bool full) const override; const char* broken() const override { @@ -477,7 +491,7 @@ class AstBracketArrayDType final : public AstNodeDType { // Associative/Queue/Normal array data type, ie "[dtype_or_expr]" // only for early parsing then becomes another data type // @astgen op1 := childDTypep : Optional[AstNodeDType] // moved to refDTypep() in V3Width - // @astgen op2 := elementsp : AstNode // ??? key dtype ??? + // @astgen op2 := elementsp : AstNode // Number of elements in array public: AstBracketArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* childDTypep, AstNode* elementsp) @@ -486,7 +500,7 @@ public: this->elementsp(elementsp); } ASTGEN_MEMBERS_AstBracketArrayDType; - bool similarDType(const AstNodeDType* samep) const override { return sameNode(samep); } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstNodeDType* subDTypep() const override VL_MT_STABLE { return childDTypep(); } // METHODS // Will be removed in V3Width, which relies on this @@ -513,7 +527,7 @@ public: const AstCDType* const asamep = VN_DBG_AS(samep, CDType); return m_name == asamep->m_name; } - bool similarDType(const AstNodeDType* samep) const override { return sameNode(samep); } + bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } string name() const override VL_MT_STABLE { return m_name; } string prettyDTypeName(bool) const override { return m_name; } // METHODS @@ -553,9 +567,7 @@ public: const AstClassRefDType* const asamep = VN_DBG_AS(samep, ClassRefDType); return (m_classp == asamep->m_classp && m_classOrPackagep == asamep->m_classOrPackagep); } - bool similarDType(const AstNodeDType* samep) const override { - return this == samep || (type() == samep->type() && sameNode(samep)); - } + bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; void dumpSmall(std::ostream& str) const override; @@ -597,7 +609,7 @@ public: const AstConstDType* const sp = VN_DBG_AS(samep, ConstDType); return (m_refDTypep == sp->m_refDTypep); } - bool similarDType(const AstNodeDType* samep) const override { + bool similarDTypeNode(const AstNodeDType* samep) const override { return skipRefp()->similarDType(samep->skipRefp()); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } @@ -630,7 +642,7 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return nullptr; } AstNodeDType* virtRefDTypep() const override { return nullptr; } void virtRefDTypep(AstNodeDType* nodep) override {} - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } @@ -667,9 +679,7 @@ public: const AstDefImplicitDType* const sp = VN_DBG_AS(samep, DefImplicitDType); return uniqueNum() == sp->uniqueNum(); } - bool similarDType(const AstNodeDType* samep) const override { - return type() == samep->type() && sameNode(samep); - } + bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { return dtypep() ? dtypep() : childDTypep(); @@ -712,11 +722,9 @@ public: if (!asamep->subDTypep()) return false; return subDTypep() == asamep->subDTypep(); } - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstDynArrayDType* const asamep = VN_DBG_AS(samep, DynArrayDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()); } string prettyDTypeName(bool full) const override; void dumpSmall(std::ostream& str) const override; @@ -748,7 +756,7 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return nullptr; } AstNodeDType* virtRefDTypep() const override { return nullptr; } void virtRefDTypep(AstNodeDType* nodep) override {} - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } @@ -790,7 +798,7 @@ public: const AstEnumDType* const sp = VN_DBG_AS(samep, EnumDType); return uniqueNum() == sp->uniqueNum(); } - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return sameNode(samep); } AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { return m_refDTypep ? m_refDTypep : childDTypep(); @@ -860,7 +868,7 @@ public: void dumpJson(std::ostream& str = std::cout) const override; void dumpSmall(std::ostream& str) const override; AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } bool isPortDecl() const { return m_portDecl; } @@ -929,7 +937,7 @@ public: void refDTypep(AstNodeDType* nodep) { m_refDTypep = nodep; } AstNodeDType* virtRefDTypep() const override { return m_refDTypep; } void virtRefDTypep(AstNodeDType* nodep) override { refDTypep(nodep); } - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } // // (Slow) recurse down to find basic data type (Note don't need virtual - // AstVar isn't a NodeDType) @@ -966,7 +974,11 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return m_subDTypep; } bool partial() const { return m_partial; } - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool sameNode(const AstNode* samep) const override { + const AstNBACommitQueueDType* const asamep = VN_DBG_AS(samep, NBACommitQueueDType); + return m_partial == asamep->m_partial; + } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 24; } @@ -995,10 +1007,9 @@ public: return dtypep() ? dtypep() : childDTypep(); } AstBasicDType* basicp() const override VL_MT_STABLE { return subDTypep()->basicp(); } - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstParamTypeDType* const sp = VN_DBG_AS(samep, ParamTypeDType); - return this->subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()); + return this->subDTypep()->similarDType(sp->subDTypep()); } int widthAlignBytes() const override { return dtypep()->widthAlignBytes(); } int widthTotalBytes() const override { return dtypep()->widthTotalBytes(); } @@ -1025,7 +1036,7 @@ public: ASTGEN_MEMBERS_AstParseTypeDType; AstNodeDType* dtypep() const VL_MT_STABLE { return nullptr; } // METHODS - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 0; } int widthTotalBytes() const override { return 0; } @@ -1064,11 +1075,9 @@ public: if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); } - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstQueueDType* const asamep = VN_DBG_AS(samep, QueueDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()); } void dumpSmall(std::ostream& str) const override; string prettyDTypeName(bool full) const override; @@ -1121,8 +1130,8 @@ public: return (m_typedefp == asamep->m_typedefp && m_refDTypep == asamep->m_refDTypep && m_name == asamep->m_name && m_classOrPackagep == asamep->m_classOrPackagep); } - bool similarDType(const AstNodeDType* samep) const override { - return skipRefp()->similarDType(samep->skipRefp()); + bool similarDTypeNode(const AstNodeDType* samep) const override { + return subDTypep()->similarDType(samep->subDTypep()); } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; @@ -1172,11 +1181,9 @@ public: if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); } - bool similarDType(const AstNodeDType* samep) const override { - if (type() != samep->type()) return false; + bool similarDTypeNode(const AstNodeDType* samep) const override { const AstSampleQueueDType* const asamep = VN_DBG_AS(samep, SampleQueueDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()); } void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } @@ -1209,7 +1216,7 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return nullptr; } AstNodeDType* virtRefDTypep() const override { return nullptr; } void virtRefDTypep(AstNodeDType* nodep) override {} - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } @@ -1238,7 +1245,7 @@ public: return nullptr; } bool sameNode(const AstNode* samep) const override; - bool similarDType(const AstNodeDType* samep) const override; + bool similarDTypeNode(const AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { @@ -1268,7 +1275,7 @@ public: AstNodeDType* subDTypep() const override VL_MT_STABLE { return nullptr; } AstNodeDType* virtRefDTypep() const override { return nullptr; } void virtRefDTypep(AstNodeDType* nodep) override {} - bool similarDType(const AstNodeDType* samep) const override { return this == samep; } + bool similarDTypeNode(const AstNodeDType* samep) const override { return this == samep; } AstBasicDType* basicp() const override VL_MT_STABLE { return nullptr; } int widthAlignBytes() const override { return 1; } int widthTotalBytes() const override { return 1; } @@ -1292,7 +1299,7 @@ public: return nullptr; } bool sameNode(const AstNode* samep) const override; - bool similarDType(const AstNodeDType* samep) const override; + bool similarDTypeNode(const AstNodeDType* samep) const override; void dumpSmall(std::ostream& str) const override; AstNodeDType* getChildDTypep() const override { return childDTypep(); } AstNodeDType* subDTypep() const override VL_MT_STABLE { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 4ada5e738..324715d98 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2358,11 +2358,9 @@ bool AstWildcardArrayDType::sameNode(const AstNode* samep) const { if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); } -bool AstWildcardArrayDType::similarDType(const AstNodeDType* samep) const { - if (type() != samep->type()) return false; +bool AstWildcardArrayDType::similarDTypeNode(const AstNodeDType* samep) const { const AstWildcardArrayDType* const asamep = VN_DBG_AS(samep, WildcardArrayDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()); } void AstSampleQueueDType::dumpSmall(std::ostream& str) const { this->AstNodeDType::dumpSmall(str); @@ -2377,11 +2375,9 @@ bool AstUnsizedArrayDType::sameNode(const AstNode* samep) const { if (!asamep->subDTypep()) return false; return (subDTypep() == asamep->subDTypep()); } -bool AstUnsizedArrayDType::similarDType(const AstNodeDType* samep) const { - if (type() != samep->type()) return false; +bool AstUnsizedArrayDType::similarDTypeNode(const AstNodeDType* samep) const { const AstUnsizedArrayDType* const asamep = VN_DBG_AS(samep, UnsizedArrayDType); - return asamep->subDTypep() - && subDTypep()->skipRefp()->similarDType(asamep->subDTypep()->skipRefp()); + return asamep->subDTypep() && subDTypep()->similarDType(asamep->subDTypep()); } void AstEmptyQueueDType::dumpSmall(std::ostream& str) const { this->AstNodeDType::dumpSmall(str); diff --git a/src/V3Hasher.cpp b/src/V3Hasher.cpp index 9b8be0dc3..ea4d0aaa9 100644 --- a/src/V3Hasher.cpp +++ b/src/V3Hasher.cpp @@ -138,6 +138,11 @@ class HasherVisitor final : public VNVisitorConst { iterateConstNull(nodep->virtRefDType2p()); }); } + void visit(AstBracketArrayDType* nodep) override { + m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [this, nodep]() { + iterateConstNull(nodep->virtRefDTypep()); + }); + } void visit(AstDynArrayDType* nodep) override { m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [this, nodep]() { // iterateConstNull(nodep->virtRefDTypep()); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index f52246941..c9bff9e6f 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -318,7 +318,7 @@ class ParamProcessor final { static string paramValueString(const AstNode* nodep) { if (const AstRefDType* const refp = VN_CAST(nodep, RefDType)) { - nodep = refp->skipRefToEnump(); + nodep = refp->skipRefToNonRefp(); } string key = nodep->name(); if (const AstIfaceRefDType* const ifrtp = VN_CAST(nodep, IfaceRefDType)) { @@ -373,7 +373,7 @@ class ParamProcessor final { // TODO: This parameter value number lookup via a constructed key string is not // particularly robust for type parameters. We should really have a type // equivalence predicate function. - if (AstRefDType* const refp = VN_CAST(nodep, RefDType)) { nodep = refp->skipRefToEnump(); } + if (AstRefDType* const refp = VN_CAST(nodep, RefDType)) nodep = refp->skipRefToNonRefp(); const string paramStr = paramValueString(nodep); // cppcheck-has-bug-suppress unreadVariable V3Hash hash = V3Hasher::uncachedHash(nodep) + paramStr; @@ -415,7 +415,7 @@ class ParamProcessor final { return nullptr; } bool isString(AstNodeDType* nodep) { - if (AstBasicDType* const basicp = VN_CAST(nodep->skipRefToEnump(), BasicDType)) + if (AstBasicDType* const basicp = VN_CAST(nodep->skipRefToNonRefp(), BasicDType)) return basicp->isString(); return false; } @@ -767,8 +767,8 @@ class ParamProcessor final { } } else if (AstParamTypeDType* const modvarp = pinp->modPTypep()) { AstNodeDType* rawTypep = VN_CAST(pinp->exprp(), NodeDType); - AstNodeDType* const exprp = rawTypep ? rawTypep->skipRefToEnump() : nullptr; - const AstNodeDType* const origp = modvarp->skipRefToEnump(); + AstNodeDType* exprp = rawTypep ? rawTypep->skipRefToNonRefp() : nullptr; + const AstNodeDType* const origp = modvarp->skipRefToNonRefp(); if (!exprp) { pinp->v3error("Parameter type pin value isn't a type: Param " << pinp->prettyNameQ() << " of " << nodep->prettyNameQ()); @@ -782,7 +782,9 @@ class ParamProcessor final { // This prevents making additional modules, and makes coverage more // obvious as it won't show up under a unique module page name. } else { - V3Const::constifyParamsEdit(exprp); + VL_DO_DANGLING(V3Const::constifyParamsEdit(exprp), exprp); + rawTypep = VN_CAST(pinp->exprp(), NodeDType); + exprp = rawTypep ? rawTypep->skipRefToNonRefp() : nullptr; longnamer += "_" + paramSmallName(srcModp, modvarp) + paramValueNumber(exprp); any_overridesr = true; } diff --git a/test_regress/t/t_mailbox_array.py b/test_regress/t/t_mailbox_array.py new file mode 100755 index 000000000..4839f3e66 --- /dev/null +++ b/test_regress/t/t_mailbox_array.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=['--fno-slice']) # TODO remove -fno-slice, issue #5632/#5644 + +test.execute() + +test.passes() diff --git a/test_regress/t/t_mailbox_array.v b/test_regress/t/t_mailbox_array.v new file mode 100644 index 000000000..0917b3cc1 --- /dev/null +++ b/test_regress/t/t_mailbox_array.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls; + localparam DWIDTH = 6; + typedef int my_type_t [2**DWIDTH]; + mailbox #(my_type_t) m_mbx; + + function new(); + this.m_mbx = new(1); + endfunction +endclass + +module tb_top(); + Cls c; + initial begin + c = new(); + $display("%p", c); + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From d7893a60ca43718b825ce3f82efc87618fcd2ea1 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 16:09:04 -0500 Subject: [PATCH 109/171] Internals: In V3LinkDot debug, show node name prefix. No functional change. --- src/V3LinkDot.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index d4eb83dbc..03fa7e396 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2228,7 +2228,9 @@ class LinkDotResolveVisitor final : public VNVisitor { std::ostringstream sstr; sstr << "ds=" << names[m_dotPos]; sstr << " dse" << cvtToHex(m_dotSymp); - sstr << "(" << m_dotSymp->nodep()->typeName() << ")"; + const string dsname = m_dotSymp->nodep()->name().substr(0, 8); + sstr << "(" << m_dotSymp->nodep()->typeName() << (dsname.empty() ? "" : ":") << dsname + << ")"; if (m_dotErr) sstr << " [dotErr]"; if (m_super) sstr << " [super]"; if (m_unresolvedCell) sstr << " [unrCell]"; From 9f8fcaf827c6a64cd3ece5481f74dc7973397fc9 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 16:09:39 -0500 Subject: [PATCH 110/171] Fix linking types of typedefs --- src/V3AstNodes.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 324715d98..72c5689bc 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2598,9 +2598,14 @@ void AstClassOrPackageRef::dump(std::ostream& str) const { void AstClassOrPackageRef::dumpJson(std::ostream& str) const { dumpJsonGen(str); } AstNodeModule* AstClassOrPackageRef::classOrPackagep() const { AstNode* foundp = m_classOrPackageNodep; - if (auto* const anodep = VN_CAST(foundp, Typedef)) foundp = anodep->subDTypep(); - if (auto* const anodep = VN_CAST(foundp, NodeDType)) foundp = anodep->skipRefp(); - if (auto* const anodep = VN_CAST(foundp, ClassRefDType)) foundp = anodep->classp(); + AstNode* lastp = nullptr; + while (foundp != lastp) { + lastp = foundp; + if (AstNodeDType* const anodep = VN_CAST(foundp, NodeDType)) foundp = anodep->skipRefp(); + if (AstTypedef* const anodep = VN_CAST(foundp, Typedef)) foundp = anodep->subDTypep(); + if (AstClassRefDType* const anodep = VN_CAST(foundp, ClassRefDType)) + foundp = anodep->classp(); + } return VN_CAST(foundp, NodeModule); } From f631587a2002a44fa11a5ba4abe25126a6ceb981 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 16:57:18 -0500 Subject: [PATCH 111/171] Internals: Rename classOrPackageSkip as kept confusing with member accessor. No functional change. --- src/V3AstNodeExpr.h | 4 +++- src/V3AstNodes.cpp | 2 +- src/V3LinkDot.cpp | 47 +++++++++++++++++++++++---------------------- src/V3Param.cpp | 5 +++-- 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 69e4d675c..cafe804b7 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -780,9 +780,11 @@ public: void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; string name() const override VL_MT_STABLE { return m_name; } // * = Var name + // There's no classOrPackagep(); use classOrPackageNodep() to get Node, + // or iterating to package with classOrPackageSkipp() + AstNodeModule* classOrPackageSkipp() const; AstNode* classOrPackageNodep() const { return m_classOrPackageNodep; } void classOrPackageNodep(AstNode* nodep) { m_classOrPackageNodep = nodep; } - AstNodeModule* classOrPackagep() const; AstPackage* packagep() const { return VN_CAST(classOrPackageNodep(), Package); } void classOrPackagep(AstNodeModule* nodep) { m_classOrPackageNodep = (AstNode*)nodep; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 72c5689bc..1685a5de5 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2596,7 +2596,7 @@ void AstClassOrPackageRef::dump(std::ostream& str) const { } } void AstClassOrPackageRef::dumpJson(std::ostream& str) const { dumpJsonGen(str); } -AstNodeModule* AstClassOrPackageRef::classOrPackagep() const { +AstNodeModule* AstClassOrPackageRef::classOrPackageSkipp() const { AstNode* foundp = m_classOrPackageNodep; AstNode* lastp = nullptr; while (foundp != lastp) { diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 03fa7e396..dceba9722 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -767,7 +767,7 @@ public: } VSymEnt* resolveClassOrPackage(VSymEnt* lookSymp, AstClassOrPackageRef* nodep, bool classOnly, const string& forWhat) { - if (nodep->classOrPackagep()) return getNodeSym(nodep->classOrPackagep()); + if (nodep->classOrPackageSkipp()) return getNodeSym(nodep->classOrPackageSkipp()); VSymEnt* foundp = lookSymp->findIdFallback(nodep->name()); if (!foundp && v3Global.rootp()->stdPackagep()) { // Look under implied std:: foundp = getNodeSym(v3Global.rootp()->stdPackagep())->findIdFlat(nodep->name()); @@ -1182,11 +1182,11 @@ class LinkDotFindVisitor final : public VNVisitor { nodep->v3warn(E_UNSUPPORTED, "Unsupported: extern function definition with class-in-class"); } else { - if (!cpackagerefp->classOrPackagep()) { + if (!cpackagerefp->classOrPackageSkipp()) { m_statep->resolveClassOrPackage(m_curSymp, cpackagerefp, false, "External definition :: reference"); } - AstClass* const classp = VN_CAST(cpackagerefp->classOrPackagep(), Class); + AstClass* const classp = VN_CAST(cpackagerefp->classOrPackageSkipp(), Class); if (!classp) { nodep->v3error("Extern declaration's scope is not a defined class"); } else { @@ -2863,14 +2863,14 @@ class LinkDotResolveVisitor final : public VNVisitor { if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; - } else if (!cpackagerefp->classOrPackagep()) { + } else if (!cpackagerefp->classOrPackageSkipp()) { VSymEnt* const foundp = m_statep->resolveClassOrPackage( m_ds.m_dotSymp, cpackagerefp, false, ":: reference"); if (!foundp) return; - classOrPackagep = cpackagerefp->classOrPackagep(); + classOrPackagep = cpackagerefp->classOrPackageSkipp(); m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); } else { - classOrPackagep = cpackagerefp->classOrPackagep(); + classOrPackagep = cpackagerefp->classOrPackageSkipp(); UASSERT_OBJ(classOrPackagep, m_ds.m_dotp->lhsp(), "Bad package link"); m_ds.m_dotSymp = m_statep->getNodeSym(classOrPackagep); } @@ -3216,7 +3216,7 @@ class LinkDotResolveVisitor final : public VNVisitor { VL_RESTORER(m_usedPins); m_usedPins.clear(); UASSERT_OBJ(m_statep->forPrimary() || VN_IS(nodep->classOrPackageNodep(), ParamTypeDType) - || nodep->classOrPackagep(), + || nodep->classOrPackageSkipp(), nodep, "ClassRef has unlinked class"); UASSERT_OBJ(m_statep->forPrimary() || !nodep->paramsp(), nodep, "class reference parameter not removed by V3Param"); @@ -3224,15 +3224,15 @@ class LinkDotResolveVisitor final : public VNVisitor { VL_RESTORER(m_ds); VL_RESTORER(m_pinSymp); - if (!nodep->classOrPackagep() && nodep->name() != "local::") { + if (!nodep->classOrPackageSkipp() && nodep->name() != "local::") { m_statep->resolveClassOrPackage(m_ds.m_dotSymp, nodep, false, ":: reference"); } // ClassRef's have pins, so track - if (nodep->classOrPackagep()) { - m_pinSymp = m_statep->getNodeSym(nodep->classOrPackagep()); + if (nodep->classOrPackageSkipp()) { + m_pinSymp = m_statep->getNodeSym(nodep->classOrPackageSkipp()); } - AstClass* const refClassp = VN_CAST(nodep->classOrPackagep(), Class); + AstClass* const refClassp = VN_CAST(nodep->classOrPackageSkipp(), Class); // Make sure any extends() are properly imported within referenced class if (refClassp && !m_statep->forPrimary()) classExtendImport(refClassp); @@ -3242,7 +3242,7 @@ class LinkDotResolveVisitor final : public VNVisitor { AstClass* const modClassp = VN_CAST(m_modp, Class); if (m_statep->forPrimary() && refClassp && !nodep->paramsp() - && nodep->classOrPackagep()->hasGParam() + && nodep->classOrPackageSkipp()->hasGParam() // Don't warn on typedefs, which are hard to know if there's a param somewhere // buried && VN_IS(nodep->classOrPackageNodep(), Class) @@ -3263,8 +3263,8 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } } - if (m_ds.m_dotPos == DP_PACKAGE && nodep->classOrPackagep()) { - m_ds.m_dotSymp = m_statep->getNodeSym(nodep->classOrPackagep()); + if (m_ds.m_dotPos == DP_PACKAGE && nodep->classOrPackageSkipp()) { + m_ds.m_dotSymp = m_statep->getNodeSym(nodep->classOrPackageSkipp()); UINFO(9, indent() << "set sym " << m_ds.ascii() << endl); } } @@ -3515,12 +3515,12 @@ class LinkDotResolveVisitor final : public VNVisitor { if (cpackagerefp->name() == "local::") { m_randSymp = nullptr; first = true; - } else if (!cpackagerefp->classOrPackagep()) { + } else if (!cpackagerefp->classOrPackageSkipp()) { VSymEnt* const foundp = m_statep->resolveClassOrPackage( m_ds.m_dotSymp, cpackagerefp, false, ":: reference"); - if (foundp) nodep->classOrPackagep(cpackagerefp->classOrPackagep()); + if (foundp) nodep->classOrPackagep(cpackagerefp->classOrPackageSkipp()); } else { - nodep->classOrPackagep(cpackagerefp->classOrPackagep()); + nodep->classOrPackagep(cpackagerefp->classOrPackageSkipp()); } // Class/package :: HERE function() . method_called_on_function_return_value() m_ds.m_dotPos = DP_MEMBER; @@ -3895,8 +3895,8 @@ class LinkDotResolveVisitor final : public VNVisitor { VSymEnt* const foundp = m_statep->resolveClassOrPackage( lookSymp, lookNodep, false, nodep->verilogKwd()); if (!foundp) return; - UASSERT_OBJ(lookNodep->classOrPackagep(), nodep, "Bad package link"); - lookSymp = m_statep->getNodeSym(lookNodep->classOrPackagep()); + UASSERT_OBJ(lookNodep->classOrPackageSkipp(), nodep, "Bad package link"); + lookSymp = m_statep->getNodeSym(lookNodep->classOrPackageSkipp()); } else { dotp->lhsp()->v3error("Attempting to extend" // LCOV_EXCL_LINE " using non-class under dot"); @@ -4068,12 +4068,12 @@ class LinkDotResolveVisitor final : public VNVisitor { iterate(cpackagep); return; } - if (!cpackagerefp->classOrPackagep()) { + if (!cpackagerefp->classOrPackageSkipp()) { VSymEnt* const foundp = m_statep->resolveClassOrPackage( m_ds.m_dotSymp, cpackagerefp, false, "class/package reference"); if (!foundp) return; } - nodep->classOrPackagep(cpackagerefp->classOrPackagep()); + nodep->classOrPackagep(cpackagerefp->classOrPackageSkipp()); if (!VN_IS(nodep->classOrPackagep(), Class) && !VN_IS(nodep->classOrPackagep(), Package)) { // Likely impossible, as error thrown earlier @@ -4094,8 +4094,9 @@ class LinkDotResolveVisitor final : public VNVisitor { UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), "Bad package link"); auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); - UASSERT_OBJ(cpackagerefp->classOrPackagep(), m_ds.m_dotp->lhsp(), "Bad package link"); - nodep->classOrPackagep(cpackagerefp->classOrPackagep()); + UASSERT_OBJ(cpackagerefp->classOrPackageSkipp(), m_ds.m_dotp->lhsp(), + "Bad package link"); + nodep->classOrPackagep(cpackagerefp->classOrPackageSkipp()); m_ds.m_dotPos = DP_SCOPE; } else { checkNoDot(nodep); diff --git a/src/V3Param.cpp b/src/V3Param.cpp index c9bff9e6f..fd5479feb 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -593,7 +593,8 @@ class ParamProcessor final { if (AstClassRefDType* const classRefp = VN_CAST(nodep, ClassRefDType)) { if (classRefp->classp() == oldClassp) classRefp->classp(newClassp); } else if (AstClassOrPackageRef* const classRefp = VN_CAST(nodep, ClassOrPackageRef)) { - if (classRefp->classOrPackagep() == oldClassp) classRefp->classOrPackagep(newClassp); + if (classRefp->classOrPackageSkipp() == oldClassp) + classRefp->classOrPackagep(newClassp); } if (nodep->op1p()) replaceRefsRecurse(nodep->op1p(), oldClassp, newClassp); @@ -1084,7 +1085,7 @@ class ParamVisitor final : public VNVisitor { if (const auto* modCellp = VN_CAST(cellp, Cell)) { srcModp = modCellp->modp(); } else if (const auto* classRefp = VN_CAST(cellp, ClassOrPackageRef)) { - srcModp = classRefp->classOrPackagep(); + srcModp = classRefp->classOrPackageSkipp(); if (VN_IS(classRefp->classOrPackageNodep(), ParamTypeDType)) continue; } else if (const auto* classRefp = VN_CAST(cellp, ClassRefDType)) { srcModp = classRefp->classp(); From 990ccd67638da2f327c0aade3246b47014a5c58f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 18:01:50 -0500 Subject: [PATCH 112/171] Internals: Standardize on `template +template class VerilatedTrace; class VerilatedTraceBaseC; class VerilatedTraceConfig; @@ -300,7 +300,7 @@ public: private: // The following are for use by Verilator internals only - template + template friend class VerilatedTrace; // Run-time trace configuration requested by this model virtual std::unique_ptr traceConfig() const; diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 3491aa376..412102476 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -71,7 +71,7 @@ public: // But only local to this file // This isn't in the header file for auto-magic conversion because it // inlines to too much code and makes compilation too slow. -template +template class VerilatedCoverItemSpec final : public VerilatedCovImpItem { private: // MEMBERS diff --git a/include/verilated_save.h b/include/verilated_save.h index 4ff97a154..724fe8298 100644 --- a/include/verilated_save.h +++ b/include/verilated_save.h @@ -300,7 +300,7 @@ inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& r VerilatedSerialize& operator<<(VerilatedSerialize& os, VerilatedContext* rhsp); VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VerilatedContext* rhsp); -template +template VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray& rhs) { os << rhs.atDefault(); const uint32_t len = rhs.size(); @@ -312,7 +312,7 @@ VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray +template VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VlAssocArray& rhs) { os >> rhs.atDefault(); uint32_t len = 0; diff --git a/include/verilated_trace.h b/include/verilated_trace.h index 87d5025b4..d5b8f76bb 100644 --- a/include/verilated_trace.h +++ b/include/verilated_trace.h @@ -41,9 +41,9 @@ // clang-format on class VlThreadPool; -template +template class VerilatedTraceBuffer; -template +template class VerilatedTraceOffloadBuffer; //============================================================================= @@ -100,7 +100,7 @@ enum class VerilatedTraceSigType : uint8_t { // Offloaded tracing // A simple synchronized first in first out queue -template +template class VerilatedThreadQueue final { // LCOV_EXCL_LINE // lcov bug private: mutable VerilatedMutex m_mutex; // Protects m_queue @@ -202,7 +202,7 @@ public: // T_Trace is the format-specific subclass of VerilatedTrace. // T_Buffer is the format-specific base class of VerilatedTraceBuffer. -template +template class VerilatedTrace VL_NOT_FINAL { public: using Buffer = VerilatedTraceBuffer; @@ -442,7 +442,7 @@ public: // T_Buffer is the format-specific base class of VerilatedTraceBuffer. // The format-specific hot-path methods use duck-typing via T_Buffer for performance. -template +template class VerilatedTraceBuffer VL_NOT_FINAL : public T_Buffer { protected: // Type of the owner trace file @@ -543,7 +543,7 @@ public: // T_Buffer is the format-specific base class of VerilatedTraceBuffer. // The format-specific hot-path methods use duck-typing via T_Buffer for performance. -template +template class VerilatedTraceOffloadBuffer final : public VerilatedTraceBuffer { using typename VerilatedTraceBuffer::Trace; diff --git a/include/verilated_types.h b/include/verilated_types.h index 2e8af51ee..fe6db1774 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -309,7 +309,7 @@ public: size_t operator()() { return VL_MASK_I(31) & vl_rand64(); } }; -template +template class VlRandC final { T_Value m_remaining = 0; // Number of values to pull before re-randomize T_Value m_lfsr = 1; // LFSR state @@ -477,7 +477,7 @@ std::string VL_TO_STRING(const VlWide& obj) { // // Bound here is the maximum size() allowed, e.g. 1 + SystemVerilog bound // For dynamic arrays it is always zero -template +template class VlQueue final { private: // TYPES @@ -485,7 +485,7 @@ private: public: using const_iterator = typename Deque::const_iterator; - template + template using WithFuncReturnType = decltype(std::declval()(0, std::declval())); private: @@ -909,7 +909,7 @@ public: } }; -template +template std::string VL_TO_STRING(const VlQueue& obj) { return obj.to_string(); } @@ -919,7 +919,7 @@ std::string VL_TO_STRING(const VlQueue& obj) { // There are no multithreaded locks on this; the base variable must // be protected by other means // -template +template class VlAssocArray final { private: // TYPES @@ -927,7 +927,7 @@ private: public: using const_iterator = typename Map::const_iterator; - template + template using WithFuncReturnType = decltype(std::declval()(std::declval(), std::declval())); @@ -1244,12 +1244,12 @@ public: } }; -template +template std::string VL_TO_STRING(const VlAssocArray& obj) { return obj.to_string(); } -template +template void VL_READMEM_N(bool hex, int bits, const std::string& filename, VlAssocArray& obj, QData start, QData end) VL_MT_SAFE { VlReadMem rmem{hex, bits, filename, start, end}; @@ -1265,7 +1265,7 @@ void VL_READMEM_N(bool hex, int bits, const std::string& filename, } } -template +template void VL_WRITEMEM_N(bool hex, int bits, const std::string& filename, const VlAssocArray& obj, QData start, QData end) VL_MT_SAFE { VlWriteMem wmem{hex, bits, filename, start, end}; @@ -1287,9 +1287,8 @@ void VL_WRITEMEM_N(bool hex, int bits, const std::string& filename, /// This class may get exposed to a Verilated Model's top I/O, if the top /// IO has an unpacked array. -template -struct VlUnpacked final { -private: +template +class VlUnpacked final { // TYPES using T_Key = IData; // Index type, for uniformity with other containers using Unpacked = T_Value[T_Depth]; @@ -1569,7 +1568,7 @@ private: } }; -template +template std::string VL_TO_STRING(const VlUnpacked& obj) { return obj.to_string(); } @@ -2027,7 +2026,7 @@ public: #define VL_KEEP_THIS \ VlClassRef::type> __Vthisref { this } -template // T typically of type VlClassRef +template // T typically of type VlClassRef inline T VL_NULL_CHECK(T t, const char* filename, int linenum) { if (VL_UNLIKELY(!t)) Verilated::nullPointerError(filename, linenum); return t; diff --git a/include/verilatedos.h b/include/verilatedos.h index f633a0f32..c96f1b022 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -701,7 +701,7 @@ reverse_wrapper reverse_view(const T& v) { // Object that is returned by this function is not considered // as MT_SAFE and any function call on this object still // needs to be `VL_MT_SAFE`. -template +template T const& as_const(T& v) VL_MT_SAFE { return v; } diff --git a/src/V3Ast.h b/src/V3Ast.h index 4169c7dc2..c298829fc 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1745,7 +1745,7 @@ public: explicit VNUser(void* p) { m_u.up = p; } ~VNUser() = default; // Casters - template + template typename std::enable_if::value, T>::type to() const VL_MT_SAFE { return reinterpret_cast(m_u.up); } diff --git a/src/V3AstUserAllocator.h b/src/V3AstUserAllocator.h index e18aea1b1..974be6b0b 100644 --- a/src/V3AstUserAllocator.h +++ b/src/V3AstUserAllocator.h @@ -27,7 +27,7 @@ #include #include -template +template class AstUserAllocatorBase VL_NOT_FINAL { static_assert(1 <= T_UserN && T_UserN <= 4, "Wrong user pointer number"); static_assert(std::is_base_of::value, "T_Node must be an AstNode type"); @@ -107,13 +107,13 @@ public: // User pointer allocator classes. T_Node is the type of node the allocator should be applied to // and is there for a bit of extra type safety. T_Data is the type of the data structure // managed by the allocator. -template +template class AstUser1Allocator final : public AstUserAllocatorBase {}; -template +template class AstUser2Allocator final : public AstUserAllocatorBase {}; -template +template class AstUser3Allocator final : public AstUserAllocatorBase {}; -template +template class AstUser4Allocator final : public AstUserAllocatorBase {}; #endif // Guard diff --git a/src/V3Const.cpp b/src/V3Const.cpp index f25116282..da37703aa 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -57,7 +57,7 @@ static bool isConst(const AstNode* nodep, uint64_t v) { return constp && constp->toUQuad() == v; } -template +template static typename std::enable_if::value, bool>::type isPow2(T val) { return (val & (val - 1)) == 0; } diff --git a/src/V3GraphAlg.h b/src/V3GraphAlg.h index 63fec5691..4a5478237 100644 --- a/src/V3GraphAlg.h +++ b/src/V3GraphAlg.h @@ -27,7 +27,7 @@ // Algorithms - common class // For internal use, most graph algorithms use this as a base class -template // Or sometimes const V3Graph +template // Or sometimes const V3Graph class GraphAlg VL_NOT_FINAL { protected: T_Graph* const m_graphp; // Graph we're operating upon diff --git a/src/V3GraphStream.h b/src/V3GraphStream.h index 7741938b0..948c762d4 100644 --- a/src/V3GraphStream.h +++ b/src/V3GraphStream.h @@ -40,7 +40,7 @@ // not generally safe. If you want a raw pointer compare, see // GraphStreamUnordered below. -template +template class GraphStream final { // TYPES class VxHolder final { diff --git a/src/V3Hash.h b/src/V3Hash.h index 1aa39b292..7ca847697 100644 --- a/src/V3Hash.h +++ b/src/V3Hash.h @@ -57,13 +57,13 @@ public: bool operator<(const V3Hash& rh) const { return m_value < rh.m_value; } // '+' combines hashes - template + template V3Hash operator+(T that) const { return V3Hash{combine(m_value, V3Hash{that}.m_value)}; } // '+=' combines in place - template + template V3Hash& operator+=(T that) { return *this = *this + that; } diff --git a/src/V3OptionParser.cpp b/src/V3OptionParser.cpp index c71a4590e..49e27fe30 100644 --- a/src/V3OptionParser.cpp +++ b/src/V3OptionParser.cpp @@ -59,7 +59,7 @@ struct V3OptionParser::Impl final { class ActionCbCall; // Callback without argument for "-opt" class ActionCbFOnOff; // Callback for "-fopt" and "-fno-opt" class ActionCbOnOff; // Callback for "-opt" and "-no-opt" - template + template class ActionCbVal; // Callback for "-opt val" class ActionCbPartialMatch; // Callback "-O3" for "-O" class ActionCbPartialMatchVal; // Callback "-debugi-V3Options 3" for "-debugi-" @@ -171,7 +171,7 @@ V3OptionParser::ActionIfs* V3OptionParser::find(const char* optp) { return nullptr; } -template +template V3OptionParser::ActionIfs& V3OptionParser::add(const std::string& opt, ARG arg) { UASSERT(!m_pimpl->m_isFinalized, "Cannot add after finalize() is called"); std::unique_ptr act{new ACT{std::move(arg)}}; diff --git a/src/V3OptionParser.h b/src/V3OptionParser.h index 9b35b9e48..8b4870168 100644 --- a/src/V3OptionParser.h +++ b/src/V3OptionParser.h @@ -65,7 +65,7 @@ private: // METHODS ActionIfs* find(const char* optp) VL_MT_DISABLED; - template + template ActionIfs& add(const string& opt, ARG arg) VL_MT_DISABLED; // Returns true if strp starts with "-fno" static bool hasPrefixFNo(const char* strp) VL_MT_DISABLED; diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index b09a7a95b..ad1be879b 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -186,7 +186,7 @@ struct SplitVarImpl VL_NOT_FINAL { static const char* cannotSplitPackedVarReason(const AstVar* varp); - template + template void insertBeginCore(T_ALWAYSLIKE* ap, AstNodeStmt* stmtp, AstNodeModule* modp) { if (ap->isJustOneBodyStmt() && ap->stmtsp() == stmtp) { stmtp->unlinkFrBack(); diff --git a/src/V3StdFuture.h b/src/V3StdFuture.h index 2e4d2f31b..0ab865b06 100644 --- a/src/V3StdFuture.h +++ b/src/V3StdFuture.h @@ -22,7 +22,7 @@ namespace vlstd { // constexpr std::max with arguments passed by value (required by constexpr before C++14) -template +template constexpr T max(T a, T b) { return a > b ? a : b; } diff --git a/src/V3String.h b/src/V3String.h index 83db7eed9..84b89a422 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -33,20 +33,20 @@ //###################################################################### // Global string-related functions -template +template std::string cvtToStr(const T& t) VL_PURE { std::ostringstream os; os << t; return os.str(); } -template +template typename std::enable_if::value, std::string>::type cvtToHex(const T tp) VL_PURE { std::ostringstream os; os << static_cast(tp); return os.str(); } -template +template typename std::enable_if::value, std::string>::type cvtToHex(const T t) { std::ostringstream os; os << std::hex << std::setw(sizeof(T) * 8 / 4) << std::setfill('0') << t; From 0c820c30689965aec1b226a41381af9964c42fb6 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 29 Nov 2024 20:20:38 -0500 Subject: [PATCH 113/171] Internals: Standardize template argument names. No functional change. --- include/verilated_funcs.h | 182 ++++++++-------- include/verilated_profiler.h | 10 +- include/verilated_random.h | 14 +- include/verilated_threads.h | 4 +- include/verilated_types.h | 410 +++++++++++++++++------------------ src/V3Active.cpp | 12 +- src/V3Ast.h | 126 +++++------ src/V3AstNodeOther.h | 25 ++- src/V3AstUserAllocator.h | 22 +- src/V3Delayed.cpp | 8 +- src/V3Dfg.h | 38 ++-- src/V3DfgAstToDfg.cpp | 6 +- src/V3DfgCache.h | 10 +- src/V3DfgDfgToAst.cpp | 6 +- src/V3EmitCBase.h | 4 +- src/V3EmitCMake.cpp | 4 +- src/V3FunctionTraits.h | 14 +- src/V3Graph.cpp | 4 +- src/V3Graph.h | 10 +- src/V3GraphPathChecker.cpp | 4 +- src/V3GraphPathChecker.h | 2 +- src/V3GraphStream.h | 8 +- src/V3List.h | 18 +- src/V3OptionParser.cpp | 20 +- src/V3OptionParser.h | 4 +- src/V3OrderParallel.cpp | 64 +++--- src/V3Randomize.cpp | 8 +- src/V3Timing.cpp | 8 +- 28 files changed, 524 insertions(+), 521 deletions(-) diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index eea56ac26..8aa30e0db 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -1604,26 +1604,26 @@ static inline IData VL_PACK_II(int obits, int lbits, const VlQueue& q) { return ret; } -template -static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { +template +static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { IData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) - ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + ret |= static_cast(q[N_Depth - 1 - i]) << (i * lbits); return ret; } -template -static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { +template +static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { IData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) - ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + ret |= static_cast(q[N_Depth - 1 - i]) << (i * lbits); return ret; } -template -static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { +template +static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked& q) { IData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) ret |= q[N_Depth - 1 - i] << (i * lbits); return ret; } @@ -1645,27 +1645,27 @@ static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue& q) { return ret; } -template -static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { +template +static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { QData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) - ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + ret |= static_cast(q[N_Depth - 1 - i]) << (i * lbits); return ret; } -template -static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { +template +static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { QData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) - ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + ret |= static_cast(q[N_Depth - 1 - i]) << (i * lbits); return ret; } -template -static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { +template +static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked& q) { QData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) - ret |= static_cast(q[T_Depth - 1 - i]) << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + ret |= static_cast(q[N_Depth - 1 - i]) << (i * lbits); return ret; } @@ -1675,10 +1675,10 @@ static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue& q) { return ret; } -template -static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked& q) { +template +static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked& q) { QData ret = 0; - for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits); + for (size_t i = 0; i < N_Depth; ++i) ret |= q[N_Depth - 1 - i] << (i * lbits); return ret; } @@ -1703,30 +1703,30 @@ static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const Vl return owp; } -template +template static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, - const VlUnpacked& q) { + const VlUnpacked& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); - for (size_t i = 0; i < T_Depth; ++i) - _vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + _vl_insert_WI(owp, q[N_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); return owp; } -template +template static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, - const VlUnpacked& q) { + const VlUnpacked& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); - for (size_t i = 0; i < T_Depth; ++i) - _vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + _vl_insert_WI(owp, q[N_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); return owp; } -template +template static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, - const VlUnpacked& q) { + const VlUnpacked& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); - for (size_t i = 0; i < T_Depth; ++i) - _vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + _vl_insert_WI(owp, q[N_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); return owp; } @@ -1737,30 +1737,30 @@ static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const Vl return owp; } -template +template static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, - const VlUnpacked& q) { + const VlUnpacked& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); - for (size_t i = 0; i < T_Depth; ++i) - _vl_insert_WQ(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + _vl_insert_WQ(owp, q[N_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); return owp; } -template +template static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp, - const VlQueue>& q) { + const VlQueue>& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); for (size_t i = 0; i < q.size(); ++i) _vl_insert_WW(owp, q.at(i), i * lbits + lbits - 1, i * lbits); return owp; } -template +template static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp, - const VlUnpacked, T_Depth>& q) { + const VlUnpacked, N_Depth>& q) { VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1); - for (size_t i = 0; i < T_Depth; ++i) - _vl_insert_WW(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); + for (size_t i = 0; i < N_Depth; ++i) + _vl_insert_WW(owp, q[N_Depth - 1 - i], i * lbits + lbits - 1, i * lbits); return owp; } @@ -2288,8 +2288,8 @@ static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue& q, WDataIn } } -template -static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue>& q, WDataInP rwp) { +template +static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue>& q, WDataInP rwp) { const int size = (rbits + lbits - 1) / lbits; q.renew(size); for (size_t i = 0; i < size; ++i) { @@ -2297,85 +2297,85 @@ static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue>& q, WDa } } -template -static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { +template +static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { +template +static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { +template +static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked& q, IData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { +template +static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { +template +static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { +template +static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked& q, QData from) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked& q, QData from) { +template +static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked& q, QData from) { const QData mask = VL_MASK_Q(lbits); - for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask; + for (size_t i = 0; i < N_Depth; ++i) q[i] = (from >> ((N_Depth - 1 - i) * lbits)) & mask; } -template -static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, +template +static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) - q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask; + for (size_t i = 0; i < N_Depth; ++i) + q[i] = VL_SEL_IWII(rbits, rwp, (N_Depth - 1 - i) * lbits, lbits) & mask; } -template -static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, +template +static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) - q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask; + for (size_t i = 0; i < N_Depth; ++i) + q[i] = VL_SEL_IWII(rbits, rwp, (N_Depth - 1 - i) * lbits, lbits) & mask; } -template -static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, +template +static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { const IData mask = VL_MASK_I(lbits); - for (size_t i = 0; i < T_Depth; ++i) - q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask; + for (size_t i = 0; i < N_Depth; ++i) + q[i] = VL_SEL_IWII(rbits, rwp, (N_Depth - 1 - i) * lbits, lbits) & mask; } -template -static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked& q, +template +static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked& q, WDataInP rwp) { const QData mask = VL_MASK_Q(lbits); - for (size_t i = 0; i < T_Depth; ++i) - q[i] = VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask; + for (size_t i = 0; i < N_Depth; ++i) + q[i] = VL_SEL_QWII(rbits, rwp, (N_Depth - 1 - i) * lbits, lbits) & mask; } -template -static inline void VL_UNPACK_WW(int lbits, int rbits, VlUnpacked, T_Depth>& q, +template +static inline void VL_UNPACK_WW(int lbits, int rbits, VlUnpacked, N_Depth>& q, WDataInP rwp) { - for (size_t i = 0; i < T_Depth; ++i) - VL_SEL_WWII(lbits, rbits, q[i], rwp, (T_Depth - 1 - i) * lbits, lbits); + for (size_t i = 0; i < N_Depth; ++i) + VL_SEL_WWII(lbits, rbits, q[i], rwp, (N_Depth - 1 - i) * lbits, lbits); } // Return QData from double (numeric) diff --git a/include/verilated_profiler.h b/include/verilated_profiler.h index 6938c338d..08210df56 100644 --- a/include/verilated_profiler.h +++ b/include/verilated_profiler.h @@ -198,7 +198,7 @@ public: //============================================================================= // VlPgoProfiler is for collecting profiling data for PGO -template +template class VlPgoProfiler final { // TYPES struct Record final { @@ -207,7 +207,7 @@ class VlPgoProfiler final { }; // Counters are stored packed, all together to reduce cache effects - std::array m_counters; // Time spent on this record + std::array m_counters; // Time spent on this record std::vector m_records; // Record information public: @@ -216,7 +216,7 @@ public: ~VlPgoProfiler() = default; void write(const char* modelp, const std::string& filename) VL_MT_SAFE; void addCounter(size_t counter, const std::string& name) { - VL_DEBUG_IF(assert(counter < T_Entries);); + VL_DEBUG_IF(assert(counter < N_Entries);); m_records.emplace_back(Record{name, counter}); } void startCounter(size_t counter) { @@ -227,8 +227,8 @@ public: void stopCounter(size_t counter) { m_counters[counter] += VL_CPU_TICK(); } }; -template -void VlPgoProfiler::write(const char* modelp, const std::string& filename) VL_MT_SAFE { +template +void VlPgoProfiler::write(const char* modelp, const std::string& filename) VL_MT_SAFE { static VerilatedMutex s_mutex; const VerilatedLockGuard lock{s_mutex}; diff --git a/include/verilated_random.h b/include/verilated_random.h index d679f3e0e..4dd840149 100644 --- a/include/verilated_random.h +++ b/include/verilated_random.h @@ -250,11 +250,11 @@ public: record_arr_table(var, name, dimension, {}); } } - template - void write_var(VlUnpacked& var, int width, const char* name, int dimension, + template + void write_var(VlUnpacked& var, int width, const char* name, int dimension, std::uint32_t randmodeIdx = std::numeric_limits::max()) { if (m_vars.find(name) != m_vars.end()) return; - m_vars[name] = std::make_shared>>( + m_vars[name] = std::make_shared>>( name, width, &var, dimension, randmodeIdx); if (dimension > 0) { idx = 0; @@ -295,11 +295,11 @@ public: ++idx; } } - template - void record_arr_table(VlUnpacked& var, const std::string name, int dimension, + template + void record_arr_table(VlUnpacked& var, const std::string name, int dimension, std::vector indices) { - if ((dimension > 0) && (N != 0)) { - for (size_t i = 0; i < N; ++i) { + if ((dimension > 0) && (N_Depth != 0)) { + for (size_t i = 0; i < N_Depth; ++i) { const std::string indexed_name = name + "[" + std::to_string(i) + "]"; indices.push_back(i); record_arr_table(var.operator[](i), indexed_name, dimension - 1, indices); diff --git a/include/verilated_threads.h b/include/verilated_threads.h index 7ba0a4f33..48a927789 100644 --- a/include/verilated_threads.h +++ b/include/verilated_threads.h @@ -161,10 +161,10 @@ public: ~VlWorkerThread(); // METHODS - template + template void dequeWork(ExecRec* workp) VL_MT_SAFE_EXCLUDES(m_mutex) { // Spin for a while, waiting for new data - if VL_CONSTEXPR_CXX17 (SpinWait) { + if VL_CONSTEXPR_CXX17 (N_SpinWait) { for (unsigned i = 0; i < VL_LOCK_SPINS; ++i) { if (VL_LIKELY(m_ready_size.load(std::memory_order_relaxed))) break; VL_CPU_RELAX(); diff --git a/include/verilated_types.h b/include/verilated_types.h index fe6db1774..a7a72d5e1 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -164,12 +164,12 @@ inline std::string VL_TO_STRING(const VlProcessRef& p) { return std::string("pro //=================================================================== // Activity trigger vector -template // +template // class VlTriggerVec final { - // TODO: static assert T_size > 0, and don't generate when empty + // TODO: static assert N_Size > 0, and don't generate when empty // MEMBERS - alignas(16) std::array(T_size) / 64> m_flags; // The flags + alignas(16) std::array(N_Size) / 64> m_flags; // The flags public: // CONSTRUCTOR @@ -200,12 +200,12 @@ public: } // Set all elements true in 'this' that are set in 'other' - void thisOr(const VlTriggerVec& other) { + void thisOr(const VlTriggerVec& other) { for (size_t i = 0; i < m_flags.size(); ++i) m_flags[i] |= other.m_flags[i]; } // Set elements of 'this' to 'a & !b' element-wise - void andNot(const VlTriggerVec& a, const VlTriggerVec& b) { + void andNot(const VlTriggerVec& a, const VlTriggerVec& b) { for (size_t i = 0; i < m_flags.size(); ++i) m_flags[i] = a.m_flags[i] & ~b.m_flags[i]; } }; @@ -309,7 +309,7 @@ public: size_t operator()() { return VL_MASK_I(31) & vl_rand64(); } }; -template +template class VlRandC final { T_Value m_remaining = 0; // Number of values to pull before re-randomize T_Value m_lfsr = 1; // LFSR state @@ -317,8 +317,8 @@ class VlRandC final { public: // CONSTRUCTORS VlRandC() { - static_assert(T_numValues >= 1, ""); - static_assert(sizeof(T_Value) == 8 || (T_numValues < (1ULL << (8 * sizeof(T_Value)))), ""); + static_assert(N_NumValues >= 1, ""); + static_assert(sizeof(T_Value) == 8 || (N_NumValues < (1ULL << (8 * sizeof(T_Value)))), ""); } // METHODS T_Value randomize(VlRNG& rngr) { @@ -337,23 +337,23 @@ public: 0x80000057ULL, // 32 0x100000029ULL // 33 }; - constexpr uint32_t clogWidth = VL_CLOG2_CE_Q(T_numValues) + 1; + constexpr uint32_t clogWidth = VL_CLOG2_CE_Q(N_NumValues) + 1; constexpr uint32_t lfsrWidth = (clogWidth < 2) ? 2 : clogWidth; constexpr T_Value polynomial = static_cast(s_polynomials[lfsrWidth]); - // printf(" numV=%ld w=%d poly=%x\n", T_numValues, lfsrWidth, polynomial); + // printf(" numV=%ld w=%d poly=%x\n", N_NumValues, lfsrWidth, polynomial); // Loop until get reasonable value. Because we picked a LFSR of at most one // extra bit in width, this will only require at most on average 1.5 loops do { m_lfsr = (m_lfsr & 1ULL) ? ((m_lfsr >> 1ULL) ^ polynomial) : (m_lfsr >> 1ULL); - } while (m_lfsr > T_numValues); // Note if == then output value 0 + } while (m_lfsr > N_NumValues); // Note if == then output value 0 --m_remaining; - T_Value result = (m_lfsr == T_numValues) ? 0 : m_lfsr; - // printf(" result=%x (numv=%ld, rem=%d)\n", result, T_numValues, m_remaining); + T_Value result = (m_lfsr == N_NumValues) ? 0 : m_lfsr; + // printf(" result=%x (numv=%ld, rem=%d)\n", result, N_NumValues, m_remaining); return result; } void reseed(VlRNG& rngr) { - constexpr uint32_t lfsrWidth = VL_CLOG2_CE_Q(T_numValues) + 1; - m_remaining = T_numValues; + constexpr uint32_t lfsrWidth = VL_CLOG2_CE_Q(N_NumValues) + 1; + m_remaining = N_NumValues; do { m_lfsr = rngr.rand64() & VL_MASK_Q(lfsrWidth); // printf(" lfsr.reseed=%x\n", m_lfsr); @@ -414,23 +414,23 @@ public: static int _vl_cmp_w(int words, WDataInP const lwp, WDataInP const rwp) VL_PURE; -template +template struct VlWide; // Type trait to check if a type is VlWide template struct VlIsVlWide : public std::false_type {}; -template -struct VlIsVlWide> : public std::true_type {}; +template +struct VlIsVlWide> : public std::true_type {}; -template +template struct VlWide final { - static constexpr size_t Words = T_Words; + static constexpr size_t Words = N_Words; // MEMBERS // This should be the only data member, otherwise generated static initializers need updating - EData m_storage[T_Words]; // Contents of the packed array + EData m_storage[N_Words]; // Contents of the packed array // CONSTRUCTORS // Default constructors and destructor are used. Note however that C++20 requires that @@ -441,8 +441,8 @@ struct VlWide final { // Default copy assignment operators are used. operator WDataOutP() VL_PURE { return &m_storage[0]; } // This also allows [] operator WDataInP() const VL_PURE { return &m_storage[0]; } // This also allows [] - bool operator!=(const VlWide& that) const VL_PURE { - for (size_t i = 0; i < T_Words; ++i) { + bool operator!=(const VlWide& that) const VL_PURE { + for (size_t i = 0; i < N_Words; ++i) { if (m_storage[i] != that.m_storage[i]) return true; } return false; @@ -453,21 +453,21 @@ struct VlWide final { EData& at(size_t index) { return m_storage[index]; } WData* data() { return &m_storage[0]; } const WData* data() const { return &m_storage[0]; } - bool operator<(const VlWide& rhs) const { - return _vl_cmp_w(T_Words, data(), rhs.data()) < 0; + bool operator<(const VlWide& rhs) const { + return _vl_cmp_w(N_Words, data(), rhs.data()) < 0; } }; // Convert a C array to std::array reference by pointer magic, without copy. // Data type (second argument) is so the function template can automatically generate. -template -VlWide& VL_CVT_W_A(const WDataInP inp, const VlWide&) { - return *((VlWide*)inp); +template +VlWide& VL_CVT_W_A(const WDataInP inp, const VlWide&) { + return *((VlWide*)inp); } -template -std::string VL_TO_STRING(const VlWide& obj) { - return VL_TO_STRING_W(T_Words, obj.data()); +template +std::string VL_TO_STRING(const VlWide& obj) { + return VL_TO_STRING_W(N_Words, obj.data()); } //=================================================================== @@ -477,7 +477,7 @@ std::string VL_TO_STRING(const VlWide& obj) { // // Bound here is the maximum size() allowed, e.g. 1 + SystemVerilog bound // For dynamic arrays it is always zero -template +template class VlQueue final { private: // TYPES @@ -485,8 +485,8 @@ private: public: using const_iterator = typename Deque::const_iterator; - template - using WithFuncReturnType = decltype(std::declval()(0, std::declval())); + template + using WithFuncReturnType = decltype(std::declval()(0, std::declval())); private: // MEMBERS @@ -506,11 +506,11 @@ public: bool operator!=(const VlQueue& rhs) const { return m_deque != rhs.m_deque; } // Standard copy constructor works. Verilog: assoca = assocb - // Also must allow conversion from a different T_MaxSize queue - template - VlQueue operator=(const VlQueue& rhs) { + // Also must allow conversion from a different N_MaxSize queue + template + VlQueue operator=(const VlQueue& rhs) { m_deque = rhs.privateDeque(); - if (VL_UNLIKELY(T_MaxSize && T_MaxSize < m_deque.size())) m_deque.resize(T_MaxSize - 1); + if (VL_UNLIKELY(N_MaxSize && N_MaxSize < m_deque.size())) m_deque.resize(N_MaxSize - 1); return *this; } @@ -562,7 +562,7 @@ public: m_deque.resize(size, atDefault()); } // Dynamic array new[]() becomes a renew_copy() - void renew_copy(size_t size, const VlQueue& rhs) { + void renew_copy(size_t size, const VlQueue& rhs) { if (size == 0) { clear(); } else { @@ -575,11 +575,11 @@ public: // function void q.push_front(value) void push_front(const T_Value& value) { m_deque.push_front(value); - if (VL_UNLIKELY(T_MaxSize != 0 && m_deque.size() > T_MaxSize)) m_deque.pop_back(); + if (VL_UNLIKELY(N_MaxSize != 0 && m_deque.size() > N_MaxSize)) m_deque.pop_back(); } // function void q.push_back(value) void push_back(const T_Value& value) { - if (VL_LIKELY(T_MaxSize == 0 || m_deque.size() < T_MaxSize)) m_deque.push_back(value); + if (VL_LIKELY(N_MaxSize == 0 || m_deque.size() < N_MaxSize)) m_deque.push_back(value); } // function value_t q.pop_front(); T_Value pop_front() { @@ -600,7 +600,7 @@ public: T_Value& atWrite(int32_t index) { // cppcheck-suppress variableScope static thread_local T_Value t_throwAway; - // Needs to work for dynamic arrays, so does not use T_MaxSize + // Needs to work for dynamic arrays, so does not use N_MaxSize if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) { t_throwAway = atDefault(); return t_throwAway; @@ -621,7 +621,7 @@ public: } // Accessing. Verilog: v = assoc[index] const T_Value& at(int32_t index) const { - // Needs to work for dynamic arrays, so does not use T_MaxSize + // Needs to work for dynamic arrays, so does not use N_MaxSize if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) { return atDefault(); } else { @@ -665,8 +665,8 @@ public: // Methods void sort() { std::sort(m_deque.begin(), m_deque.end()); } - template - void sort(Func with_func) { + template + void sort(T_Func with_func) { // with_func returns arbitrary type to use for the sort comparison std::sort(m_deque.begin(), m_deque.end(), [=](const T_Value& a, const T_Value& b) { // index number is meaningless with sort, as it changes @@ -674,8 +674,8 @@ public: }); } void rsort() { std::sort(m_deque.rbegin(), m_deque.rend()); } - template - void rsort(Func with_func) { + template + void rsort(T_Func with_func) { // with_func returns arbitrary type to use for the sort comparison std::sort(m_deque.rbegin(), m_deque.rend(), [=](const T_Value& a, const T_Value& b) { // index number is meaningless with sort, as it changes @@ -696,8 +696,8 @@ public: } return out; } - template - VlQueue unique(Func with_func) const { + template + VlQueue unique(T_Func with_func) const { VlQueue out; std::set saw; for (const auto& i : m_deque) { @@ -724,8 +724,8 @@ public: } return out; } - template - VlQueue unique_index(Func with_func) const { + template + VlQueue unique_index(T_Func with_func) const { VlQueue out; IData index = 0; std::set saw; @@ -740,8 +740,8 @@ public: } return out; } - template - VlQueue find(Func with_func) const { + template + VlQueue find(T_Func with_func) const { VlQueue out; IData index = 0; for (const auto& i : m_deque) { @@ -750,8 +750,8 @@ public: } return out; } - template - VlQueue find_index(Func with_func) const { + template + VlQueue find_index(T_Func with_func) const { VlQueue out; IData index = 0; for (const auto& i : m_deque) { @@ -760,8 +760,8 @@ public: } return out; } - template - VlQueue find_first(Func with_func) const { + template + VlQueue find_first(T_Func with_func) const { // Can't use std::find_if as need index number IData index = 0; for (const auto& i : m_deque) { @@ -770,8 +770,8 @@ public: } return VlQueue{}; } - template - VlQueue find_first_index(Func with_func) const { + template + VlQueue find_first_index(T_Func with_func) const { IData index = 0; for (const auto& i : m_deque) { if (with_func(index, i)) return VlQueue::consV(index); @@ -779,8 +779,8 @@ public: } return VlQueue{}; } - template - VlQueue find_last(Func with_func) const { + template + VlQueue find_last(T_Func with_func) const { IData index = m_deque.size() - 1; for (auto& item : vlstd::reverse_view(m_deque)) { if (with_func(index, item)) return VlQueue::consV(item); @@ -788,8 +788,8 @@ public: } return VlQueue{}; } - template - VlQueue find_last_index(Func with_func) const { + template + VlQueue find_last_index(T_Func with_func) const { IData index = m_deque.size() - 1; for (auto& item : vlstd::reverse_view(m_deque)) { if (with_func(index, item)) return VlQueue::consV(index); @@ -804,8 +804,8 @@ public: const auto it = std::min_element(m_deque.cbegin(), m_deque.cend()); return VlQueue::consV(*it); } - template - VlQueue min(Func with_func) const { + template + VlQueue min(T_Func with_func) const { if (m_deque.empty()) return VlQueue{}; const auto it = std::min_element(m_deque.cbegin(), m_deque.cend(), [&with_func](const IData& a, const IData& b) { @@ -818,8 +818,8 @@ public: const auto it = std::max_element(m_deque.cbegin(), m_deque.cend()); return VlQueue::consV(*it); } - template - VlQueue max(Func with_func) const { + template + VlQueue max(T_Func with_func) const { if (m_deque.empty()) return VlQueue{}; const auto it = std::max_element(m_deque.cbegin(), m_deque.cend(), [&with_func](const IData& a, const IData& b) { @@ -833,9 +833,9 @@ public: for (const auto& i : m_deque) out += i; return out; } - template - WithFuncReturnType r_sum(Func with_func) const { - WithFuncReturnType out = WithFuncReturnType(0); + template + WithFuncReturnType r_sum(T_Func with_func) const { + WithFuncReturnType out = WithFuncReturnType(0); IData index = 0; for (const auto& i : m_deque) out += with_func(index++, i); return out; @@ -846,10 +846,10 @@ public: for (const auto& i : m_deque) out *= i; return out; } - template - WithFuncReturnType r_product(Func with_func) const { - if (m_deque.empty()) return WithFuncReturnType(0); // The big three do it this way - WithFuncReturnType out = WithFuncReturnType(1); + template + WithFuncReturnType r_product(T_Func with_func) const { + if (m_deque.empty()) return WithFuncReturnType(0); // The big three do it this way + WithFuncReturnType out = WithFuncReturnType(1); IData index = 0; for (const auto& i : m_deque) out *= with_func(index++, i); return out; @@ -860,11 +860,11 @@ public: for (const auto& i : m_deque) out &= i; return out; } - template - WithFuncReturnType r_and(Func with_func) const { - if (m_deque.empty()) return WithFuncReturnType(0); // The big three do it this way + template + WithFuncReturnType r_and(T_Func with_func) const { + if (m_deque.empty()) return WithFuncReturnType(0); // The big three do it this way IData index = 0; - WithFuncReturnType out = ~WithFuncReturnType(0); + WithFuncReturnType out = ~WithFuncReturnType(0); for (const auto& i : m_deque) out &= with_func(index++, i); return out; } @@ -873,9 +873,9 @@ public: for (const auto& i : m_deque) out |= i; return out; } - template - WithFuncReturnType r_or(Func with_func) const { - WithFuncReturnType out = WithFuncReturnType(0); + template + WithFuncReturnType r_or(T_Func with_func) const { + WithFuncReturnType out = WithFuncReturnType(0); IData index = 0; for (const auto& i : m_deque) out |= with_func(index++, i); return out; @@ -888,9 +888,9 @@ public: for (const auto& i : m_deque) out ^= i; return out; } - template - WithFuncReturnType r_xor(Func with_func) const { - WithFuncReturnType out = WithFuncReturnType(0); + template + WithFuncReturnType r_xor(T_Func with_func) const { + WithFuncReturnType out = WithFuncReturnType(0); IData index = 0; for (const auto& i : m_deque) out ^= with_func(index++, i); return out; @@ -909,8 +909,8 @@ public: } }; -template -std::string VL_TO_STRING(const VlQueue& obj) { +template +std::string VL_TO_STRING(const VlQueue& obj) { return obj.to_string(); } @@ -927,9 +927,9 @@ private: public: using const_iterator = typename Map::const_iterator; - template + template using WithFuncReturnType - = decltype(std::declval()(std::declval(), std::declval())); + = decltype(std::declval()(std::declval(), std::declval())); private: // MEMBERS @@ -1038,8 +1038,8 @@ public: } return out; } - template - VlQueue unique(Func with_func) const { + template + VlQueue unique(T_Func with_func) const { VlQueue out; T_Key default_key; using WithType = decltype(with_func(m_map.begin()->first, m_map.begin()->second)); @@ -1066,8 +1066,8 @@ public: } return out; } - template - VlQueue unique_index(Func with_func) const { + template + VlQueue unique_index(T_Func with_func) const { VlQueue out; using WithType = decltype(with_func(m_map.begin()->first, m_map.begin()->second)); std::set saw; @@ -1081,22 +1081,22 @@ public: } return out; } - template - VlQueue find(Func with_func) const { + template + VlQueue find(T_Func with_func) const { VlQueue out; for (const auto& i : m_map) if (with_func(i.first, i.second)) out.push_back(i.second); return out; } - template - VlQueue find_index(Func with_func) const { + template + VlQueue find_index(T_Func with_func) const { VlQueue out; for (const auto& i : m_map) if (with_func(i.first, i.second)) out.push_back(i.first); return out; } - template - VlQueue find_first(Func with_func) const { + template + VlQueue find_first(T_Func with_func) const { const auto it = std::find_if(m_map.cbegin(), m_map.cend(), [=](const std::pair& i) { return with_func(i.first, i.second); @@ -1104,8 +1104,8 @@ public: if (it == m_map.end()) return VlQueue{}; return VlQueue::consV(it->second); } - template - VlQueue find_first_index(Func with_func) const { + template + VlQueue find_first_index(T_Func with_func) const { const auto it = std::find_if(m_map.cbegin(), m_map.cend(), [=](const std::pair& i) { return with_func(i.first, i.second); @@ -1113,16 +1113,16 @@ public: if (it == m_map.end()) return VlQueue{}; return VlQueue::consV(it->first); } - template - VlQueue find_last(Func with_func) const { + template + VlQueue find_last(T_Func with_func) const { const auto it = std::find_if( m_map.crbegin(), m_map.crend(), [=](const std::pair& i) { return with_func(i.first, i.second); }); if (it == m_map.rend()) return VlQueue{}; return VlQueue::consV(it->second); } - template - VlQueue find_last_index(Func with_func) const { + template + VlQueue find_last_index(T_Func with_func) const { const auto it = std::find_if( m_map.crbegin(), m_map.crend(), [=](const std::pair& i) { return with_func(i.first, i.second); }); @@ -1140,8 +1140,8 @@ public: }); return VlQueue::consV(it->second); } - template - VlQueue min(Func with_func) const { + template + VlQueue min(T_Func with_func) const { if (m_map.empty()) return VlQueue(); const auto it = std::min_element( m_map.cbegin(), m_map.cend(), @@ -1159,8 +1159,8 @@ public: }); return VlQueue::consV(it->second); } - template - VlQueue max(Func with_func) const { + template + VlQueue max(T_Func with_func) const { if (m_map.empty()) return VlQueue(); const auto it = std::max_element( m_map.cbegin(), m_map.cend(), @@ -1175,9 +1175,9 @@ public: for (const auto& i : m_map) out += i.second; return out; } - template - WithFuncReturnType r_sum(Func with_func) const { - WithFuncReturnType out = WithFuncReturnType(0); + template + WithFuncReturnType r_sum(T_Func with_func) const { + WithFuncReturnType out = WithFuncReturnType(0); for (const auto& i : m_map) out += with_func(i.first, i.second); return out; } @@ -1187,10 +1187,10 @@ public: for (const auto& i : m_map) out *= i.second; return out; } - template - WithFuncReturnType r_product(Func with_func) const { - if (m_map.empty()) return WithFuncReturnType(0); // The big three do it this way - WithFuncReturnType out = WithFuncReturnType(1); + template + WithFuncReturnType r_product(T_Func with_func) const { + if (m_map.empty()) return WithFuncReturnType(0); // The big three do it this way + WithFuncReturnType out = WithFuncReturnType(1); for (const auto& i : m_map) out *= with_func(i.first, i.second); return out; } @@ -1200,10 +1200,10 @@ public: for (const auto& i : m_map) out &= i.second; return out; } - template - WithFuncReturnType r_and(Func with_func) const { - if (m_map.empty()) return WithFuncReturnType(0); // The big three do it this way - WithFuncReturnType out = ~WithFuncReturnType(0); + template + WithFuncReturnType r_and(T_Func with_func) const { + if (m_map.empty()) return WithFuncReturnType(0); // The big three do it this way + WithFuncReturnType out = ~WithFuncReturnType(0); for (const auto& i : m_map) out &= with_func(i.first, i.second); return out; } @@ -1212,8 +1212,8 @@ public: for (const auto& i : m_map) out |= i.second; return out; } - template - T_Value r_or(Func with_func) const { + template + T_Value r_or(T_Func with_func) const { T_Value out = T_Value(0); for (const auto& i : m_map) out |= with_func(i.first, i.second); return out; @@ -1223,9 +1223,9 @@ public: for (const auto& i : m_map) out ^= i.second; return out; } - template - WithFuncReturnType r_xor(Func with_func) const { - WithFuncReturnType out = WithFuncReturnType(0); + template + WithFuncReturnType r_xor(T_Func with_func) const { + WithFuncReturnType out = WithFuncReturnType(0); for (const auto& i : m_map) out ^= with_func(i.first, i.second); return out; } @@ -1287,11 +1287,11 @@ void VL_WRITEMEM_N(bool hex, int bits, const std::string& filename, /// This class may get exposed to a Verilated Model's top I/O, if the top /// IO has an unpacked array. -template +template class VlUnpacked final { // TYPES using T_Key = IData; // Index type, for uniformity with other containers - using Unpacked = T_Value[T_Depth]; + using Unpacked = T_Value[N_Depth]; public: // MEMBERS @@ -1312,41 +1312,41 @@ public: WData* data() { return &m_storage[0]; } const WData* data() const { return &m_storage[0]; } - std::size_t size() const { return T_Depth; } + std::size_t size() const { return N_Depth; } // To fit C++14 - template + template int find_length(int dimension, std::false_type) const { return size(); } - template + template int find_length(int dimension, std::true_type) const { - if (dimension == CurrentDimension) { + if (dimension == N_CurrentDimension) { return size(); } else { - return m_storage[0].template find_length(dimension); + return m_storage[0].template find_length(dimension); } } - template + template int find_length(int dimension) const { - return find_length(dimension, std::is_class{}); + return find_length(dimension, std::is_class{}); } - template + template auto& find_element(const std::vector& indices, std::false_type) { - return m_storage[indices[CurrentDimension]]; + return m_storage[indices[N_CurrentDimension]]; } - template + template auto& find_element(const std::vector& indices, std::true_type) { - return m_storage[indices[CurrentDimension]].template find_element( - indices); + return m_storage[indices[N_CurrentDimension]] + .template find_element(indices); } - template + template auto& find_element(const std::vector& indices) { - return find_element(indices, std::is_class{}); + return find_element(indices, std::is_class{}); } T_Value& operator[](size_t index) { return m_storage[index]; } @@ -1354,15 +1354,15 @@ public: // *this != that, which might be used for change detection/trigger computation, but avoid // operator overloading in VlUnpacked for safety in other contexts. - bool neq(const VlUnpacked& that) const { return neq(*this, that); } + bool neq(const VlUnpacked& that) const { return neq(*this, that); } // Similar to 'neq' above, *this = that used for change detection - void assign(const VlUnpacked& that) { *this = that; } - bool operator==(const VlUnpacked& that) const { return !neq(that); } - bool operator!=(const VlUnpacked& that) const { return neq(that); } + void assign(const VlUnpacked& that) { *this = that; } + bool operator==(const VlUnpacked& that) const { return !neq(that); } + bool operator!=(const VlUnpacked& that) const { return neq(that); } // interface to C style arrays (used in ports), see issue #5125 - bool neq(const T_Value that[T_Depth]) const { return neq(*this, that); } - void assign(const T_Value that[T_Depth]) { std::copy_n(that, T_Depth, m_storage); } - void operator=(const T_Value that[T_Depth]) { assign(that); } + bool neq(const T_Value that[N_Depth]) const { return neq(*this, that); } + void assign(const T_Value that[N_Depth]) { std::copy_n(that, N_Depth, m_storage); } + void operator=(const T_Value that[N_Depth]) { assign(that); } // inside (set membership operator) bool inside(const T_Value& value) const { @@ -1370,8 +1370,8 @@ public: } void sort() { std::sort(std::begin(m_storage), std::end(m_storage)); } - template - void sort(Func with_func) { + template + void sort(T_Func with_func) { // with_func returns arbitrary type to use for the sort comparison std::sort(std::begin(m_storage), std::end(m_storage), [=](const T_Value& a, const T_Value& b) { @@ -1383,8 +1383,8 @@ public: void rsort() { std::sort(std::begin(m_storage), std::end(m_storage), std::greater()); } - template - void rsort(Func with_func) { + template + void rsort(T_Func with_func) { // with_func returns arbitrary type to use for the sort comparison // std::rbegin/std::rend not available until C++14, so using > below std::sort(std::begin(m_storage), std::end(m_storage), @@ -1407,8 +1407,8 @@ public: } return out; } - template - VlQueue unique(Func with_func) const { + template + VlQueue unique(T_Func with_func) const { VlQueue out; std::set saw; for (const auto& i : m_storage) { @@ -1435,8 +1435,8 @@ public: } return out; } - template - VlQueue unique_index(Func with_func) const { + template + VlQueue unique_index(T_Func with_func) const { VlQueue out; IData index = 0; std::set saw; @@ -1451,8 +1451,8 @@ public: } return out; } - template - VlQueue find(Func with_func) const { + template + VlQueue find(T_Func with_func) const { VlQueue out; IData index = 0; for (const auto& i : m_storage) { @@ -1461,8 +1461,8 @@ public: } return out; } - template - VlQueue find_index(Func with_func) const { + template + VlQueue find_index(T_Func with_func) const { VlQueue out; IData index = 0; for (const auto& i : m_storage) { @@ -1471,8 +1471,8 @@ public: } return out; } - template - VlQueue find_first(Func with_func) const { + template + VlQueue find_first(T_Func with_func) const { // Can't use std::find_if as need index number IData index = 0; for (const auto& i : m_storage) { @@ -1481,8 +1481,8 @@ public: } return VlQueue{}; } - template - VlQueue find_first_index(Func with_func) const { + template + VlQueue find_first_index(T_Func with_func) const { IData index = 0; for (const auto& i : m_storage) { if (with_func(index, i)) return VlQueue::consV(index); @@ -1490,16 +1490,16 @@ public: } return VlQueue{}; } - template - VlQueue find_last(Func with_func) const { - for (int i = T_Depth - 1; i >= 0; i--) { + template + VlQueue find_last(T_Func with_func) const { + for (int i = N_Depth - 1; i >= 0; i--) { if (with_func(i, m_storage[i])) return VlQueue::consV(m_storage[i]); } return VlQueue{}; } - template - VlQueue find_last_index(Func with_func) const { - for (int i = T_Depth - 1; i >= 0; i--) { + template + VlQueue find_last_index(T_Func with_func) const { + for (int i = N_Depth - 1; i >= 0; i--) { if (with_func(i, m_storage[i])) return VlQueue::consV(i); } return VlQueue{}; @@ -1510,8 +1510,8 @@ public: const auto it = std::min_element(std::begin(m_storage), std::end(m_storage)); return VlQueue::consV(*it); } - template - VlQueue min(Func with_func) const { + template + VlQueue min(T_Func with_func) const { const auto it = std::min_element(std::begin(m_storage), std::end(m_storage), [&with_func](const IData& a, const IData& b) { return with_func(0, a) < with_func(0, b); @@ -1522,8 +1522,8 @@ public: const auto it = std::max_element(std::begin(m_storage), std::end(m_storage)); return VlQueue::consV(*it); } - template - VlQueue max(Func with_func) const { + template + VlQueue max(T_Func with_func) const { const auto it = std::max_element(std::begin(m_storage), std::end(m_storage), [&with_func](const IData& a, const IData& b) { return with_func(0, a) < with_func(0, b); @@ -1535,7 +1535,7 @@ public: std::string to_string() const { std::string out = "'{"; std::string comma; - for (int i = 0; i < T_Depth; ++i) { + for (int i = 0; i < N_Depth; ++i) { out += comma + VL_TO_STRING(m_storage[i]); comma = ", "; } @@ -1543,18 +1543,18 @@ public: } private: - template - static bool neq(const VlUnpacked& a, const VlUnpacked& b) { - for (size_t i = 0; i < T_Dep; ++i) { + template + static bool neq(const VlUnpacked& a, const VlUnpacked& b) { + for (size_t i = 0; i < N_Dep; ++i) { // Recursive 'neq', in case T_Val is also a VlUnpacked<_, _> if (neq(a.m_storage[i], b.m_storage[i])) return true; } return false; } - template - static bool neq(const VlUnpacked& a, const T_Val b[T_Dep]) { - for (size_t i = 0; i < T_Dep; ++i) { + template + static bool neq(const VlUnpacked& a, const T_Val b[N_Dep]) { + for (size_t i = 0; i < N_Dep; ++i) { // Recursive 'neq', in case T_Val is also a VlUnpacked<_, _> if (neq(a.m_storage[i], b[i])) return true; } @@ -1568,25 +1568,25 @@ private: } }; -template -std::string VL_TO_STRING(const VlUnpacked& obj) { +template +std::string VL_TO_STRING(const VlUnpacked& obj) { return obj.to_string(); } //=================================================================== // Helper to apply the given indices to a target expression -template +template struct VlApplyIndices final { VL_ATTR_ALWINLINE static auto& apply(T_Target& target, const size_t* indicesp) { - return VlApplyIndices::apply( - target[indicesp[Curr]], indicesp); + return VlApplyIndices::apply( + target[indicesp[N_Curr]], indicesp); } }; -template -struct VlApplyIndices final { +template +struct VlApplyIndices final { VL_ATTR_ALWINLINE static T_Target& apply(T_Target& target, const size_t*) { return target; } }; @@ -1621,17 +1621,17 @@ template class VlNBACommitQueue; // Specialization for whole element updates only -template -class VlNBACommitQueue final { +template +class VlNBACommitQueue final { // TYPES struct Entry final { T_Element value; - size_t indices[T_Rank]; + size_t indices[N_Rank]; }; // STATE @@ -1643,8 +1643,8 @@ public: VL_UNCOPYABLE(VlNBACommitQueue); // METHODS - template - void enqueue(const T_Element& value, Args... indices) { + template + void enqueue(const T_Element& value, T_Args... indices) { m_pending.emplace_back(Entry{value, {indices...}}); } @@ -1654,20 +1654,20 @@ public: void commit(T_Commit& target) { if (m_pending.empty()) return; for (const Entry& entry : m_pending) { - VlApplyIndices<0, T_Rank, T_Commit>::apply(target, entry.indices) = entry.value; + VlApplyIndices<0, N_Rank, T_Commit>::apply(target, entry.indices) = entry.value; } m_pending.clear(); } }; // With partial element updates -template -class VlNBACommitQueue final { +template +class VlNBACommitQueue final { // TYPES struct Entry final { T_Element value; T_Element mask; - size_t indices[T_Rank]; + size_t indices[N_Rank]; }; // STATE @@ -1728,8 +1728,8 @@ public: VL_UNCOPYABLE(VlNBACommitQueue); // METHODS - template - void enqueue(const T_Element& value, const T_Element& mask, Args... indices) { + template + void enqueue(const T_Element& value, const T_Element& mask, T_Args... indices) { m_pending.emplace_back(Entry{value, mask, {indices...}}); } @@ -1739,7 +1739,7 @@ public: void commit(T_Commit& target) { if (m_pending.empty()) return; for (const Entry& entry : m_pending) { // - auto& ref = VlApplyIndices<0, T_Rank, T_Commit>::apply(target, entry.indices); + auto& ref = VlApplyIndices<0, N_Rank, T_Commit>::apply(target, entry.indices); // Maybe inefficient, but it works for now ... const auto oldValue = ref; ref = bOr(bAnd(entry.value, entry.mask), bAnd(oldValue, bNot(entry.mask))); @@ -1961,13 +1961,13 @@ public: }; }; -template -static inline bool VL_CAST_DYNAMIC(VlClassRef in, VlClassRef& outr) { +template +static inline bool VL_CAST_DYNAMIC(VlClassRef in, VlClassRef& outr) { if (!in) { outr = VlNull{}; return true; } - VlClassRef casted = in.template dynamicCast(); + VlClassRef casted = in.template dynamicCast(); if (VL_LIKELY(casted)) { outr = casted; return true; @@ -1976,8 +1976,8 @@ static inline bool VL_CAST_DYNAMIC(VlClassRef in, VlClassRef& outr) { } } -template -static inline bool VL_CAST_DYNAMIC(VlNull in, VlClassRef& outr) { +template +static inline bool VL_CAST_DYNAMIC(VlNull in, VlClassRef& outr) { outr = VlNull{}; return true; } diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 6c6070574..290f872cf 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -230,7 +230,7 @@ class ActiveNamer final : public VNVisitor { void visit(AstNode* nodep) override { iterateChildren(nodep); } // Specialized below for the special sensitivity classes - template + template AstActive*& getSpecialActive(); public: @@ -246,17 +246,17 @@ public: } // Make a new AstActive sensitive to the given special sensitivity class and return it - template + template AstActive* makeSpecialActive(FileLine* const fl) { - AstSenTree* const senTreep = new AstSenTree{fl, new AstSenItem{fl, SenItemKind{}}}; + AstSenTree* const senTreep = new AstSenTree{fl, new AstSenItem{fl, T_SenItemKind{}}}; return makeActive(fl, senTreep); } // Return an AstActive sensitive to the given special sensitivity class (possibly pre-created) - template + template AstActive* getSpecialActive(FileLine* fl) { - AstActive*& cachep = getSpecialActive(); - if (!cachep) cachep = makeSpecialActive(fl); + AstActive*& cachep = getSpecialActive(); + if (!cachep) cachep = makeSpecialActive(fl); return cachep; } diff --git a/src/V3Ast.h b/src/V3Ast.h index c298829fc..cbee6890a 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2553,21 +2553,21 @@ protected: inline static bool privateTypeTest(const AstNode* nodep); // For internal use only. - template + template constexpr static bool uselessCast() VL_PURE { - using NonRef = typename std::remove_reference::type; + using NonRef = typename std::remove_reference::type; using NonPtr = typename std::remove_pointer::type; using NonCV = typename std::remove_cv::type; - return std::is_base_of::value; + return std::is_base_of::value; } // For internal use only. - template + template constexpr static bool impossibleCast() VL_PURE { - using NonRef = typename std::remove_reference::type; + using NonRef = typename std::remove_reference::type; using NonPtr = typename std::remove_pointer::type; using NonCV = typename std::remove_cv::type; - return !std::is_base_of::value; + return !std::is_base_of::value; } public: @@ -2655,12 +2655,12 @@ private: using ConstCorrectAstNode = typename std::conditional::value, const AstNode, AstNode>::type; - template - inline static void foreachImpl(ConstCorrectAstNode* nodep, const Callable& f, + template + inline static void foreachImpl(ConstCorrectAstNode* nodep, const T_Callable& f, bool visitNext); - template - inline static bool predicateImpl(ConstCorrectAstNode* nodep, const Callable& p); + template + inline static bool predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p); public: // Given a callable 'f' that takes a single argument of some AstNode subtype 'T_Node', traverse @@ -2670,46 +2670,48 @@ public: // handle a single (or a few) node types, as it's easier to write, but more importantly, the // dispatch to the callable in 'foreach' should be completely predictable by branch target // caches in modern CPUs, while it is basically unpredictable for VNVisitor. - template - void foreach(Callable&& f) { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable::value + template + void foreach(T_Callable&& f) { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable::value && std::is_base_of::value, - "Callable 'f' must have a signature compatible with 'void(T_Node*)', " + "T_Callable 'f' must have a signature compatible with 'void(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ false); } // Same as above, but for 'const' nodes - template - void foreach(Callable&& f) const { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable::value - && std::is_base_of::value, - "Callable 'f' must have a signature compatible with 'void(const T_Node*)', " - "with 'T_Node' being a subtype of 'AstNode'"); + template + void foreach(T_Callable&& f) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert( + vlstd::is_invocable::value + && std::is_base_of::value, + "T_Callable 'f' must have a signature compatible with 'void(const T_Node*)', " + "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ false); } // Same as 'foreach' but also traverses 'this->nextp()' transitively - template - void foreachAndNext(Callable&& f) { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable::value + template + void foreachAndNext(T_Callable&& f) { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable::value && std::is_base_of::value, - "Callable 'f' must have a signature compatible with 'void(T_Node*)', " + "T_Callable 'f' must have a signature compatible with 'void(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ true); } // Same as above, but for 'const' nodes - template - void foreachAndNext(Callable&& f) const { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable::value - && std::is_base_of::value, - "Callable 'f' must have a signature compatible with 'void(const T_Node*)', " - "with 'T_Node' being a subtype of 'AstNode'"); + template + void foreachAndNext(T_Callable&& f) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert( + vlstd::is_invocable::value + && std::is_base_of::value, + "T_Callable 'f' must have a signature compatible with 'void(const T_Node*)', " + "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ true); } @@ -2718,50 +2720,50 @@ public: // that satisfies the predicate 'p'. Returns false if no node of type 'T_Node' is present. // Traversal is performed in some arbitrary order and is terminated as soon as the result can // be determined. - template - bool exists(Callable&& p) { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable_r::value + template + bool exists(T_Callable&& p) { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p); } // Same as above, but for 'const' nodes - template - bool exists(Callable&& p) const { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable_r::value + template + bool exists(T_Callable&& p) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p); } // Given a predicate 'p' that takes a single argument of some AstNode subtype 'T_Node', return // true if and only if all nodes of type 'T_Node' in the tree rooted at this node satisfy the // predicate 'p'. Returns true if no node of type 'T_Node' is present. Traversal is performed // in some arbitrary order and is terminated as soon as the result can be determined. - template - bool forall(Callable&& p) { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable_r::value + template + bool forall(T_Callable&& p) { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p); } // Same as above, but for 'const' nodes - template - bool forall(Callable&& p) const { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable_r::value + template + bool forall(T_Callable&& p) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p); } int nodeCount() const { @@ -2834,8 +2836,8 @@ constexpr bool AstNode::isLeaf() { } // foreach implementation -template -void AstNode::foreachImpl(ConstCorrectAstNode* nodep, const Callable& f, bool visitNext) { +template +void AstNode::foreachImpl(ConstCorrectAstNode* nodep, const T_Callable& f, bool visitNext) { // Pre-order traversal implemented directly (without recursion) for speed reasons. The very // first iteration (the one that operates on the input nodep) is special, as we might or // might not need to enqueue nodep->nextp() depending on VisitNext, while in all other @@ -2915,8 +2917,8 @@ void AstNode::foreachImpl(ConstCorrectAstNode* nodep, const Callable& f, } // predicate implementation -template -bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const Callable& p) { +template +bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p) { // Implementation similar to foreach, but abort traversal as soon as result is determined using T_Arg_NonConst = typename std::remove_const::type; using Node = ConstCorrectAstNode; @@ -2951,7 +2953,7 @@ bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const Callable& p // Type test this node if (AstNode::privateTypeTest(currp)) { // Call the client function - if (p(static_cast(currp)) != Default) return true; + if (p(static_cast(currp)) != N_Default) return true; // Short circuit if iterating leaf nodes if VL_CONSTEXPR_CXX17 (isLeaf()) return false; } @@ -2968,7 +2970,7 @@ bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const Callable& p }; // Visit the root node - if (visit(nodep)) return !Default; + if (visit(nodep)) return !N_Default; // Visit the rest of the tree while (VL_LIKELY(topp > basep)) { @@ -2985,10 +2987,10 @@ bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const Callable& p if (headp->nextp()) *topp++ = headp->nextp(); // Visit the head node - if (visit(headp)) return !Default; + if (visit(headp)) return !N_Default; } - return Default; + return N_Default; } inline std::ostream& operator<<(std::ostream& os, const AstNode* rhs) { diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index c171f5098..155237d80 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2401,13 +2401,13 @@ public: // Iterates top level members of the class, taking into account inheritance (starting from the // root superclass). Note: after V3Scope, several children are moved under an AstScope and will // not be found by this. - template - void foreachMember(const Callable& f) { - using T_Node = typename FunctionArgNoPointerNoCV::type; + template + void foreachMember(const T_Callable& f) { + using T_Node = typename FunctionArgNoPointerNoCV::type; static_assert( - vlstd::is_invocable::value + vlstd::is_invocable::value && std::is_base_of::value, - "Callable 'f' must have a signature compatible with 'void(AstClass*, T_Node*)', " + "T_Callable 'f' must have a signature compatible with 'void(AstClass*, T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); if (AstClassExtends* const cextendsp = this->extendsp()) { cextendsp->classp()->foreachMember(f); @@ -2417,13 +2417,14 @@ public: } } // Same as above, but stops after first match - template - bool existsMember(const Callable& p) const { - using T_Node = typename FunctionArgNoPointerNoCV::type; - static_assert(vlstd::is_invocable_r::value - && std::is_base_of::value, - "Predicate 'p' must have a signature compatible with 'bool(const AstClass*, " - "const T_Node*)', with 'T_Node' being a subtype of 'AstNode'"); + template + bool existsMember(const T_Callable& p) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert( + vlstd::is_invocable_r::value + && std::is_base_of::value, + "Predicate 'p' must have a signature compatible with 'bool(const AstClass*, " + "const T_Node*)', with 'T_Node' being a subtype of 'AstNode'"); if (AstClassExtends* const cextendsp = this->extendsp()) { if (cextendsp->classp()->existsMember(p)) return true; } diff --git a/src/V3AstUserAllocator.h b/src/V3AstUserAllocator.h index 974be6b0b..fdef7e36c 100644 --- a/src/V3AstUserAllocator.h +++ b/src/V3AstUserAllocator.h @@ -27,22 +27,22 @@ #include #include -template +template class AstUserAllocatorBase VL_NOT_FINAL { - static_assert(1 <= T_UserN && T_UserN <= 4, "Wrong user pointer number"); + static_assert(1 <= N_UserN && N_UserN <= 4, "Wrong user pointer number"); static_assert(std::is_base_of::value, "T_Node must be an AstNode type"); private: std::deque m_allocated; T_Data* getUserp(const T_Node* nodep) const { - if VL_CONSTEXPR_CXX17 (T_UserN == 1) { + if VL_CONSTEXPR_CXX17 (N_UserN == 1) { const VNUser user = nodep->user1u(); return user.to(); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 2) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 2) { const VNUser user = nodep->user2u(); return user.to(); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 3) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 3) { const VNUser user = nodep->user3u(); return user.to(); } else { @@ -52,11 +52,11 @@ private: } void setUserp(T_Node* nodep, T_Data* userp) const { - if VL_CONSTEXPR_CXX17 (T_UserN == 1) { + if VL_CONSTEXPR_CXX17 (N_UserN == 1) { nodep->user1u(VNUser{userp}); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 2) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 2) { nodep->user2u(VNUser{userp}); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 3) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 3) { nodep->user3u(VNUser{userp}); } else { nodep->user4u(VNUser{userp}); @@ -65,11 +65,11 @@ private: protected: AstUserAllocatorBase() { - if VL_CONSTEXPR_CXX17 (T_UserN == 1) { + if VL_CONSTEXPR_CXX17 (N_UserN == 1) { VNUser1InUse::check(); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 2) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 2) { VNUser2InUse::check(); - } else if VL_CONSTEXPR_CXX17 (T_UserN == 3) { + } else if VL_CONSTEXPR_CXX17 (N_UserN == 3) { VNUser3InUse::check(); } else { VNUser4InUse::check(); diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 31f21e5b2..82b0b156d 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -534,17 +534,17 @@ class DelayedVisitor final : public VNVisitor { } // Scheme::ValueQueuePartial/Scheme::ValueQueueWhole - template + template void prepareSchemeValueQueue(AstVarScope* vscp, VarScopeInfo& vscpInfo) { - UASSERT_OBJ(Partial ? vscpInfo.m_scheme == Scheme::ValueQueuePartial - : vscpInfo.m_scheme == Scheme::ValueQueueWhole, + UASSERT_OBJ(N_Partial ? vscpInfo.m_scheme == Scheme::ValueQueuePartial + : vscpInfo.m_scheme == Scheme::ValueQueueWhole, vscp, "Inconsistencheme"); FileLine* const flp = vscp->fileline(); AstScope* const scopep = vscp->scopep(); // Create the commit queue variable auto* const cqDTypep - = new AstNBACommitQueueDType{flp, vscp->dtypep()->skipRefp(), Partial}; + = new AstNBACommitQueueDType{flp, vscp->dtypep()->skipRefp(), N_Partial}; v3Global.rootp()->typeTablep()->addTypesp(cqDTypep); const std::string name = "__VdlyCommitQueue" + vscp->varp()->shortName(); AstVarScope* const queueVscp = createTemp(flp, scopep, name, cqDTypep); diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 5fab278ee..880517370 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -427,52 +427,52 @@ public: // Implementation of dataflow graph vertices with a fixed number of sources //------------------------------------------------------------------------------ -template +template class DfgVertexWithArity VL_NOT_FINAL : public DfgVertex { - static_assert(1 <= Arity && Arity <= 4, "Arity must be between 1 and 4 inclusive"); + static_assert(1 <= N_Arity && N_Arity <= 4, "N_Arity must be between 1 and 4 inclusive"); - std::array m_srcs; // Source edges + std::array m_srcs; // Source edges protected: DfgVertexWithArity(DfgGraph& dfg, VDfgType type, FileLine* flp, AstNodeDType* dtypep) : DfgVertex{dfg, type, flp, dtypep} { // Initialize source edges - for (size_t i = 0; i < Arity; ++i) m_srcs[i].init(this); + for (size_t i = 0; i < N_Arity; ++i) m_srcs[i].init(this); } ~DfgVertexWithArity() override = default; public: std::pair sourceEdges() final override { // - return {m_srcs.data(), Arity}; + return {m_srcs.data(), N_Arity}; } std::pair sourceEdges() const final override { - return {m_srcs.data(), Arity}; + return {m_srcs.data(), N_Arity}; } - template + template DfgEdge* sourceEdge() { - static_assert(Index < Arity, "Source index out of range"); - return &m_srcs[Index]; + static_assert(N_Index < N_Arity, "Source index out of range"); + return &m_srcs[N_Index]; } - template + template const DfgEdge* sourceEdge() const { - static_assert(Index < Arity, "Source index out of range"); - return &m_srcs[Index]; + static_assert(N_Index < N_Arity, "Source index out of range"); + return &m_srcs[N_Index]; } - template + template DfgVertex* source() const { - static_assert(Index < Arity, "Source index out of range"); - return m_srcs[Index].sourcep(); + static_assert(N_Index < N_Arity, "Source index out of range"); + return m_srcs[N_Index].sourcep(); } - template + template void relinkSource(DfgVertex* newSourcep) { - static_assert(Index < Arity, "Source index out of range"); - UASSERT_OBJ(m_srcs[Index].sinkp() == this, this, "Inconsistent"); - m_srcs[Index].relinkSource(newSourcep); + static_assert(N_Index < N_Arity, "Source index out of range"); + UASSERT_OBJ(m_srcs[N_Index].sinkp() == this, this, "Inconsistent"); + m_srcs[N_Index].relinkSource(newSourcep); } }; diff --git a/src/V3DfgAstToDfg.cpp b/src/V3DfgAstToDfg.cpp index f61380f77..2f941b9e5 100644 --- a/src/V3DfgAstToDfg.cpp +++ b/src/V3DfgAstToDfg.cpp @@ -37,9 +37,9 @@ namespace { // Create a DfgVertex out of a AstNodeExpr. For most AstNodeExpr subtypes, this can be done // automatically. For the few special cases, we provide specializations below -template -Vertex* makeVertex(const Node* nodep, DfgGraph& dfg) { - return new Vertex{dfg, nodep->fileline(), DfgVertex::dtypeFor(nodep)}; +template +T_Vertex* makeVertex(const T_Node* nodep, DfgGraph& dfg) { + return new T_Vertex{dfg, nodep->fileline(), DfgVertex::dtypeFor(nodep)}; } //====================================================================== diff --git a/src/V3DfgCache.h b/src/V3DfgCache.h index 09df39f6c..ca43a6d3c 100644 --- a/src/V3DfgCache.h +++ b/src/V3DfgCache.h @@ -157,8 +157,8 @@ public: }; }; -template -using Cache = std::unordered_map; +template +using Cache = std::unordered_map; using CacheSel = Cache; using CacheUnary = Cache; @@ -246,10 +246,10 @@ inline void setOperands(DfgVertexTernary* vtxp, DfgVertex* src0p, DfgVertex* src } // Get or create (and insert) vertex with given operands -template -inline Vertex* getOrCreate(DfgGraph& dfg, FileLine* flp, AstNodeDType* dtypep, Cache& cache, +template +inline Vertex* getOrCreate(DfgGraph& dfg, FileLine* flp, AstNodeDType* dtypep, T_Cache& cache, Operands... operands) { - typename Cache::mapped_type& entrypr = getEntry(cache, dtypep, operands...); + typename T_Cache::mapped_type& entrypr = getEntry(cache, dtypep, operands...); if (!entrypr) { Vertex* const newp = new Vertex{dfg, flp, dtypep}; setOperands(newp, operands...); diff --git a/src/V3DfgDfgToAst.cpp b/src/V3DfgDfgToAst.cpp index ee7b0c078..423ed6600 100644 --- a/src/V3DfgDfgToAst.cpp +++ b/src/V3DfgDfgToAst.cpp @@ -40,9 +40,9 @@ namespace { // Create an AstNodeExpr out of a DfgVertex. For most AstNodeExpr subtypes, this can be done // automatically. For the few special cases, we provide specializations below -template -Node* makeNode(const Vertex* vtxp, Ops... ops) { - Node* const nodep = new Node{vtxp->fileline(), ops...}; +template +T_Node* makeNode(const T_Vertex* vtxp, Ops... ops) { + T_Node* const nodep = new T_Node{vtxp->fileline(), ops...}; UASSERT_OBJ(nodep->width() == static_cast(vtxp->width()), vtxp, "Incorrect width in AstNode created from DfgVertex " << vtxp->typeName() << ": " << nodep->width() << " vs " << vtxp->width()); diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index 28bdf76a8..f82323f63 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -146,8 +146,8 @@ public: void emitCFuncDecl(const AstCFunc* funcp, const AstNodeModule* modp, bool cLinkage = false); void emitVarDecl(const AstVar* nodep, bool asRef = false); void emitVarAccessors(const AstVar* nodep); - template - static void forModCUse(const AstNodeModule* modp, VUseType useType, F action) { + template + static void forModCUse(const AstNodeModule* modp, VUseType useType, T_Callable action) { for (AstNode* itemp = modp->stmtsp(); itemp; itemp = itemp->nextp()) { if (AstCUse* const usep = VN_CAST(itemp, CUse)) { if (usep->useType().containsAny(useType)) { diff --git a/src/V3EmitCMake.cpp b/src/V3EmitCMake.cpp index 0bd768a94..b35fc2886 100644 --- a/src/V3EmitCMake.cpp +++ b/src/V3EmitCMake.cpp @@ -36,8 +36,8 @@ class CMakeEmitter final { // STATIC FUNCTIONS // Concatenate all strings in 'strs' with ' ' between them. - template - static string cmake_list(const List& strs) { + template + static string cmake_list(const T_List& strs) { string s; for (auto it = strs.begin(); it != strs.end(); ++it) { s += '"'; diff --git a/src/V3FunctionTraits.h b/src/V3FunctionTraits.h index 9287048b8..c5e1a4c16 100644 --- a/src/V3FunctionTraits.h +++ b/src/V3FunctionTraits.h @@ -32,25 +32,25 @@ struct FunctionTraits final : public FunctionTraits::type::operator())> {}; // Specialization for pointers to member function -template -struct FunctionTraits VL_NOT_FINAL { +template +struct FunctionTraits VL_NOT_FINAL { // Number of arguments static constexpr size_t arity = sizeof...(Args); // Type of result - using result_type = ReturnType; + using result_type = T_ReturnType; // Type of arguments - template + template struct arg final { - using type = typename std::tuple_element>::type; + using type = typename std::tuple_element>::type; }; }; -template +template struct FunctionArgNoPointerNoCV final { using Traits = FunctionTraits; - using T_Arg = typename Traits::template arg::type; + using T_Arg = typename Traits::template arg::type; using T_ArgNoPtr = typename std::remove_pointer::type; using type = typename std::remove_cv::type; }; diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index 968e4c261..b4a3adf08 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -79,12 +79,12 @@ void V3GraphVertex::rerouteEdges(V3Graph* graphp) { unlinkEdges(graphp); } -template +template V3GraphEdge* V3GraphVertex::findConnectingEdgep(V3GraphVertex* waywardp) { // O(edges) linear search. Searches search both nodes' edge lists in // parallel. The lists probably aren't _both_ huge, so this is // unlikely to blow up even on fairly nasty graphs. - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay inv = way.invert(); auto& aEdges = this->edges(); auto aIt = aEdges.begin(); diff --git a/src/V3Graph.h b/src/V3Graph.h index 911c909b3..765907947 100644 --- a/src/V3Graph.h +++ b/src/V3Graph.h @@ -187,9 +187,9 @@ public: uint64_t user() const { return m_user; } V3GraphVertex* fromp() const { return m_fromp; } V3GraphVertex* top() const { return m_top; } - template + template V3GraphVertex* furtherp() const { - return T_Way == GraphWay::FORWARD ? top() : fromp(); + return N_Way == GraphWay::FORWARD ? top() : fromp(); } // STATIC ACCESSORS static bool followNotCutable(const V3GraphEdge* edgep) { return !edgep->m_cutable; } @@ -301,9 +301,9 @@ public: void* userp() const VL_MT_STABLE { return m_userp; } V3GraphEdge::IList& inEdges() { return m_ins; } const V3GraphEdge::IList& inEdges() const { return m_ins; } - template + template inline auto& edges(); - template + template inline const auto& edges() const; bool inEmpty() const { return m_ins.empty(); } bool inSize1() const { return m_ins.hasSingleElement(); } @@ -320,7 +320,7 @@ public: void rerouteEdges(V3Graph* graphp) VL_MT_DISABLED; // Find the edge connecting this vertex to the given vertex. // If edge is not found returns nullptr. O(edges) performance. - template + template V3GraphEdge* findConnectingEdgep(V3GraphVertex* otherp) VL_MT_DISABLED; }; diff --git a/src/V3GraphPathChecker.cpp b/src/V3GraphPathChecker.cpp index f7f72cdfb..14930d378 100644 --- a/src/V3GraphPathChecker.cpp +++ b/src/V3GraphPathChecker.cpp @@ -53,9 +53,9 @@ struct GraphPCNode final { //###################################################################### // GraphPathChecker implementation -template +template void GraphPathChecker::initHalfCriticalPaths(bool checkOnly) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay rev = way.invert(); GraphStreamUnordered order(m_graphp, way); while (const V3GraphVertex* const vertexp = order.nextp()) { diff --git a/src/V3GraphPathChecker.h b/src/V3GraphPathChecker.h index 495d8cca8..761d45ff7 100644 --- a/src/V3GraphPathChecker.h +++ b/src/V3GraphPathChecker.h @@ -53,7 +53,7 @@ public: private: bool pathExistsInternal(const V3GraphVertex* ap, const V3GraphVertex* bp, unsigned* costp = nullptr) VL_MT_DISABLED; - template + template void initHalfCriticalPaths(bool checkOnly) VL_MT_DISABLED; void incGeneration() { ++m_generation; } diff --git a/src/V3GraphStream.h b/src/V3GraphStream.h index 948c762d4..5ddab8087 100644 --- a/src/V3GraphStream.h +++ b/src/V3GraphStream.h @@ -264,9 +264,9 @@ public: } private: - template // + template // VL_ATTR_NOINLINE void init(V3Graph* graphp) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; // Assign every vertex without an incoming edge to ready, others to waiting for (V3GraphVertex& vertex : graphp->vertices()) { const uint32_t nDeps = vertex.edges().size(); @@ -275,9 +275,9 @@ private: } } - template // + template // VL_ATTR_NOINLINE const V3GraphVertex* unblock(const V3GraphVertex* resultp) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; for (const V3GraphEdge& edge : resultp->edges()) { V3GraphVertex* const vertexp = edge.furtherp(); #if VL_DEBUG diff --git a/src/V3List.h b/src/V3List.h index c35ec4b2d..99c435f9c 100644 --- a/src/V3List.h +++ b/src/V3List.h @@ -89,7 +89,7 @@ class V3List final { // Iterator class template for V3List. This is just enough to support range based for loops // and basic usage. Feel free to extend as required. - template + template class SimpleItertatorImpl final { static_assert(std::is_same::value || std::is_same::value, @@ -99,7 +99,7 @@ class V3List final { template & (B::*)(), typename> friend class V3List; - using IteratorType = SimpleItertatorImpl; + using IteratorType = SimpleItertatorImpl; T_Base* m_currp; // Currently iterated element, or 'nullptr' for 'end()' iterator @@ -109,7 +109,7 @@ class V3List final { VL_ATTR_ALWINLINE static T_Base* step(T_Base* currp) { - if VL_CONSTEXPR_CXX17 (T_Reverse) { + if VL_CONSTEXPR_CXX17 (N_Reverse) { return toLinks(currp).m_prevp; } else { return toLinks(currp).m_nextp; @@ -145,8 +145,8 @@ class V3List final { bool operator!=(const IteratorType& other) const { return m_currp != other.m_currp; } // Convert to const iterator VL_ATTR_ALWINLINE - operator SimpleItertatorImpl() const { - return SimpleItertatorImpl{m_currp}; + operator SimpleItertatorImpl() const { + return SimpleItertatorImpl{m_currp}; } }; @@ -221,10 +221,10 @@ class V3List final { }; public: - using iterator = SimpleItertatorImpl; - using const_iterator = SimpleItertatorImpl; - using reverse_iterator = SimpleItertatorImpl; - using const_reverse_iterator = SimpleItertatorImpl; + using iterator = SimpleItertatorImpl; + using const_iterator = SimpleItertatorImpl; + using reverse_iterator = SimpleItertatorImpl; + using const_reverse_iterator = SimpleItertatorImpl; // CONSTRUCTOR V3List() = default; diff --git a/src/V3OptionParser.cpp b/src/V3OptionParser.cpp index 49e27fe30..917cd4e9d 100644 --- a/src/V3OptionParser.cpp +++ b/src/V3OptionParser.cpp @@ -37,14 +37,14 @@ struct V3OptionParser::Impl final { VALUE // "-opt val" }; // Base class of actual action classes - template + template class ActionBase VL_NOT_FINAL : public ActionIfs { bool m_undocumented = false; // This option is not documented public: - bool isValueNeeded() const override final { return MODE == en::VALUE; } - bool isFOnOffAllowed() const override final { return MODE == en::FONOFF; } - bool isOnOffAllowed() const override final { return MODE == en::ONOFF; } - bool isPartialMatchAllowed() const override final { return ALLOW_PARTIAL_MATCH; } + bool isValueNeeded() const override final { return N_Mode == en::VALUE; } + bool isFOnOffAllowed() const override final { return N_Mode == en::FONOFF; } + bool isOnOffAllowed() const override final { return N_Mode == en::ONOFF; } + bool isPartialMatchAllowed() const override final { return N_Allow_Partial_Match; } bool isUndocumented() const override { return m_undocumented; } void undocumented() override { m_undocumented = true; } }; @@ -52,9 +52,9 @@ struct V3OptionParser::Impl final { // Actual action classes template class ActionSet; // "-opt" for bool-ish, "-opt val" for int and string - template + template class ActionFOnOff; // "-fopt" and "-fno-opt" for bool-ish - template + template class ActionOnOff; // "-opt" and "-no-opt" for bool-ish class ActionCbCall; // Callback without argument for "-opt" class ActionCbFOnOff; // Callback for "-fopt" and "-fno-opt" @@ -171,10 +171,10 @@ V3OptionParser::ActionIfs* V3OptionParser::find(const char* optp) { return nullptr; } -template -V3OptionParser::ActionIfs& V3OptionParser::add(const std::string& opt, ARG arg) { +template +V3OptionParser::ActionIfs& V3OptionParser::add(const std::string& opt, T_Arg arg) { UASSERT(!m_pimpl->m_isFinalized, "Cannot add after finalize() is called"); - std::unique_ptr act{new ACT{std::move(arg)}}; + std::unique_ptr act{new T_Act{std::move(arg)}}; UASSERT(opt.size() >= 2, opt << " is too short"); UASSERT(opt[0] == '-' || opt[0] == '+', opt << " does not start with either '-' or '+'"); UASSERT(!(opt[0] == '-' && opt[1] == '-'), "Option must have single '-', but " << opt); diff --git a/src/V3OptionParser.h b/src/V3OptionParser.h index 8b4870168..d6160081b 100644 --- a/src/V3OptionParser.h +++ b/src/V3OptionParser.h @@ -65,8 +65,8 @@ private: // METHODS ActionIfs* find(const char* optp) VL_MT_DISABLED; - template - ActionIfs& add(const string& opt, ARG arg) VL_MT_DISABLED; + template + ActionIfs& add(const string& opt, T_Arg arg) VL_MT_DISABLED; // Returns true if strp starts with "-fno" static bool hasPrefixFNo(const char* strp) VL_MT_DISABLED; // Returns true if strp starts with "-no" diff --git a/src/V3OrderParallel.cpp b/src/V3OrderParallel.cpp index cc614b211..ffb9ff1da 100644 --- a/src/V3OrderParallel.cpp +++ b/src/V3OrderParallel.cpp @@ -268,7 +268,7 @@ static_assert(!std::is_polymorphic::value, "Should not have a vtable" class MTaskEdge final : public V3GraphEdge, public MergeCandidate { VL_RTTI_IMPL(MTaskEdge, V3GraphEdge) friend class LogicMTask; - template + template friend class PropagateCp; // MEMBERS @@ -280,7 +280,7 @@ public: // CONSTRUCTORS MTaskEdge(V3Graph* graphp, LogicMTask* fromp, LogicMTask* top, int weight); // METHODS - template + template inline LogicMTask* furtherMTaskp() const; inline LogicMTask* fromMTaskp() const; inline LogicMTask* toMTaskp() const; @@ -307,7 +307,7 @@ private: class LogicMTask final : public V3GraphVertex { VL_RTTI_IMPL(LogicMTask, V3GraphVertex) - template + template friend class PropagateCp; public: @@ -419,28 +419,28 @@ public: #endif } - template + template void addRelativeEdge(MTaskEdge* edgep) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay inv = way.invert(); // Add to the edge heap - LogicMTask* const relativep = edgep->furtherMTaskp(); + LogicMTask* const relativep = edgep->furtherMTaskp(); // Value is !way cp to this edge const uint32_t cp = relativep->stepCost() + relativep->critPathCost(inv); // m_edgeHeap[way].insert(&edgep->m_edgeHeapNode[way], {relativep->id(), cp}); } - template + template void stealRelativeEdge(MTaskEdge* edgep) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; // Make heap node insertable, ruining the heap it is currently in. edgep->m_edgeHeapNode[way].yank(); // Add the edge as new - addRelativeEdge(edgep); + addRelativeEdge(edgep); } - template + template void removeRelativeEdge(MTaskEdge* edgep) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; // Remove from the edge heap m_edgeHeap[way].remove(&edgep->m_edgeHeapNode[way]); } @@ -456,12 +456,12 @@ public: } bool hasRelativeMTask(LogicMTask* relativep) const { return m_edgeSet.count(relativep); } - template + template void checkRelativesCp() const { - constexpr GraphWay way{T_Way}; - for (const V3GraphEdge& edge : edges()) { + constexpr GraphWay way{N_Way}; + for (const V3GraphEdge& edge : edges()) { const LogicMTask* const relativep - = static_cast(edge.furtherp()); + = static_cast(edge.furtherp()); const uint32_t cachedCp = static_cast(edge).cachedCp(way); const uint32_t cp = relativep->critPathCost(way.invert()) + relativep->stepCost(); partCheckCachedScoreVsActual(cachedCp, cp); @@ -479,14 +479,14 @@ public: void setCritPathCost(GraphWay way, uint32_t cost) { m_critPathCost[way] = cost; } uint32_t critPathCost(GraphWay way) const { return m_critPathCost[way]; } - template + template uint32_t critPathCostWithout(const V3GraphEdge* withoutp) const { - const GraphWay way{T_Way}; + const GraphWay way{N_Way}; const GraphWay inv = way.invert(); // Compute the critical path cost wayward to this node, without considering edge // 'withoutp'. We need to look at two edges at most, the critical path if that is not via // 'withoutp', or the second-worst path, if the critical path is via 'withoutp'. - UDEBUGONLY(UASSERT(withoutp->furtherp() == this, + UDEBUGONLY(UASSERT(withoutp->furtherp() == this, "In critPathCostWithout(), edge 'withoutp' must further to 'this'");); const EdgeHeap& edgeHeap = m_edgeHeap[inv]; const EdgeHeap::Node* const maxp = edgeHeap.max(); @@ -690,9 +690,9 @@ MTaskEdge::MTaskEdge(V3Graph* graphp, LogicMTask* fromp, LogicMTask* top, int we top->addRelativeEdge(this); } -template +template LogicMTask* MTaskEdge::furtherMTaskp() const { - return static_cast(this->furtherp()); + return static_cast(this->furtherp()); } LogicMTask* MTaskEdge::fromMTaskp() const { return static_cast(fromp()); } LogicMTask* MTaskEdge::toMTaskp() const { return static_cast(top()); } @@ -716,9 +716,9 @@ void MTaskEdge::resetCriticalPaths() { // Look at vertex costs (in one way) to form critical paths for each // vertex. -template +template static void partInitHalfCriticalPaths(V3Graph& mTaskGraph, bool checkOnly) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay rev = way.invert(); GraphStreamUnordered order{&mTaskGraph, way}; for (const V3GraphVertex* vertexp; (vertexp = order.nextp());) { @@ -776,7 +776,7 @@ static void partCheckCriticalPaths(V3Graph& mTaskGraph) { // ###################################################################### // PropagateCp -template +template class PropagateCp final { // Propagate increasing critical path (CP) costs through a graph. // @@ -862,7 +862,7 @@ private: public: void cpHasIncreased(V3GraphVertex* vxp, uint32_t newInclusiveCp) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay inv{way.invert()}; // For *vxp, whose CP-inclusive has just increased to @@ -871,7 +871,7 @@ public: for (V3GraphEdge& graphEdge : vxp->edges()) { MTaskEdge& edge = static_cast(graphEdge); - LogicMTask* const relativep = edge.furtherMTaskp(); + LogicMTask* const relativep = edge.furtherMTaskp(); EdgeHeap::Node& edgeHeapNode = edge.m_edgeHeapNode[inv]; if (newInclusiveCp > edgeHeapNode.key().m_score) { relativep->m_edgeHeap[inv].increaseKey(&edgeHeapNode, newInclusiveCp); @@ -899,7 +899,7 @@ public: } void go() { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; constexpr GraphWay inv{way.invert()}; // m_pending maps each pending vertex to the amount that it wayward @@ -982,7 +982,7 @@ public: partInitCriticalPaths(graph); - PropagateCp prop{true}; + PropagateCp prop{true}; // Seed the propagator with every input node; // This should result in the complete graph getting all CP's assigned. @@ -1316,9 +1316,9 @@ public: } private: - template + template NewCp newCp(LogicMTask* mtaskp, LogicMTask* otherp, MTaskEdge* mergeEdgep) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; // Return new wayward-CP for mtaskp reflecting its upcoming merge // with otherp. Set 'result.propagate' if mtaskp's wayward // relatives will see a new wayward CP from this merge. @@ -1528,9 +1528,9 @@ private: } } - template + template void siblingPairFromRelatives(V3GraphVertex* mtaskp) { - constexpr GraphWay way{T_Way}; + constexpr GraphWay way{N_Way}; // Need at least 2 edges auto& edges = mtaskp->edges(); if (!edges.hasMultipleElements()) return; @@ -1575,7 +1575,7 @@ private: // Just make a few pairs. constexpr size_t MAX_NONEXHAUSTIVE_PAIRS = 3; - if (Exhaustive || n <= 2 * MAX_NONEXHAUSTIVE_PAIRS) { + if (N_Exhaustive || n <= 2 * MAX_NONEXHAUSTIVE_PAIRS) { const size_t end = n & ~static_cast(1); // Round down to even, (we want pairs) std::sort(sortRecs.begin(), sortRecs.begin() + n); for (size_t i = 0; i < end; i += 2) { diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index c920cc1cb..b6507c960 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -934,14 +934,14 @@ class CaptureVisitor final : public VNVisitor { return false; } - template - void fixupClassOrPackage(AstNode* memberp, NodeT refp) { + template + void fixupClassOrPackage(AstNode* memberp, T_Node refp) { AstNodeModule* const declClassp = VN_AS(memberp->user2p(), NodeModule); if (declClassp != m_targetp) refp->classOrPackagep(declClassp); } - template - bool isReferenceToInnerMember(NodeT nodep) { + template + bool isReferenceToInnerMember(T_Node nodep) { return VN_IS(nodep->fromp(), LambdaArgRef); } diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index ff0514d40..d8cc6bee9 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -233,8 +233,8 @@ class TimingSuspendableVisitor final : public VNVisitor { if (passFlag(parentp, depp, flag)) propagateFlags(depVxp, flag); } } - template - void propagateFlagsIf(DepVtx* const vxp, NodeFlag flag, Predicate p) { + template + void propagateFlagsIf(DepVtx* const vxp, NodeFlag flag, T_Predicate p) { auto* const parentp = vxp->nodep(); for (V3GraphEdge& edge : vxp->outEdges()) { auto* const depVxp = static_cast(edge.top()); @@ -242,8 +242,8 @@ class TimingSuspendableVisitor final : public VNVisitor { if (p(&edge) && passFlag(parentp, depp, flag)) propagateFlagsIf(depVxp, flag, p); } } - template - void propagateFlagsReversedIf(DepVtx* const vxp, NodeFlag flag, Predicate p) { + template + void propagateFlagsReversedIf(DepVtx* const vxp, NodeFlag flag, T_Predicate p) { auto* const parentp = vxp->nodep(); for (V3GraphEdge& edge : vxp->inEdges()) { auto* const depVxp = static_cast(edge.fromp()); From e44f34dde380d1b554485ac03c3623a4a04d45d3 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 18:56:00 -0500 Subject: [PATCH 114/171] Improve concat lint error & cleanups for future commit. --- src/V3AstNodeExpr.h | 9 ++++++--- src/V3AstNodes.cpp | 2 ++ src/V3Width.cpp | 20 ++++++++++++-------- test_regress/t/t_unpacked_concat_bad.out | 4 ++++ test_regress/t/t_unpacked_concat_bad3.out | 9 +++++++-- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index cafe804b7..5237268e6 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -1738,7 +1738,8 @@ class AstPatMember final : public AstNodeExpr { // @astgen op2 := keyp : Optional[AstNode] // @astgen op3 := repp : Optional[AstNodeExpr] // replication count, or nullptr for count 1 // @astgen op4 := varrefp : Optional[AstNodeExpr] // Decoded variable if TEXT - bool m_default = false; + bool m_isDefault = false; // Has default + bool m_isConcat = false; // From concatenate public: AstPatMember(FileLine* fl, AstNodeExpr* lhssp, AstNode* keyp, AstNodeExpr* repp) @@ -1755,8 +1756,10 @@ public: int instrCount() const override { return widthInstrs() * 2; } void dump(std::ostream& str = std::cout) const override; void dumpJson(std::ostream& str = std::cout) const override; - bool isDefault() const { return m_default; } - void isDefault(bool flag) { m_default = flag; } + bool isConcat() const { return m_isConcat; } + void isConcat(bool flag) { m_isConcat = flag; } + bool isDefault() const { return m_isDefault; } + void isDefault(bool flag) { m_isDefault = flag; } }; class AstPattern final : public AstNodeExpr { // Verilog '{a,b,c,d...} diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 1685a5de5..7f4c57e0e 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2263,9 +2263,11 @@ void AstPackageImport::pkgNameFrom() { } void AstPatMember::dump(std::ostream& str) const { this->AstNodeExpr::dump(str); + if (isConcat()) str << " [CONCAT]"; if (isDefault()) str << " [DEFAULT]"; } void AstPatMember::dumpJson(std::ostream& str) const { + if (isConcat()) dumpJsonBoolFunc(str, isConcat); if (isDefault()) dumpJsonBoolFunc(str, isDefault); dumpJsonGen(str); } diff --git a/src/V3Width.cpp b/src/V3Width.cpp index f4a7c714a..51848261c 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -573,7 +573,6 @@ class WidthVisitor final : public VNVisitor { // to determine if value or push userIterateAndNext(nodep->lhsp(), WidthVP{vdtypep, PRELIM}.p()); userIterateAndNext(nodep->rhsp(), WidthVP{vdtypep, PRELIM}.p()); - // Queue "element 0" is lhsp, so we need to swap arguments const bool lhsIsValue = AstNode::computeCastable(adtypep->subDTypep(), nodep->lhsp()->dtypep(), nullptr) .isAssignable(); @@ -4537,6 +4536,7 @@ class WidthVisitor final : public VNVisitor { UINFO(9, "ent " << range.left() << " to " << range.right() << endl); AstNode* newp = nullptr; bool allConstant = true; + const bool isConcat = nodep->itemsp() && VN_AS(nodep->itemsp(), PatMember)->isConcat(); for (int entn = 0, ent = range.left(); entn < range.elements(); ++entn, ent += range.leftToRightInc()) { AstPatMember* newpatp = nullptr; @@ -4546,10 +4546,10 @@ class WidthVisitor final : public VNVisitor { if (defaultp) { newpatp = defaultp->cloneTree(false); patp = newpatp; - } else if (!(VN_IS(arrayDtp, UnpackArrayDType) && !allConstant)) { + } else if (!(VN_IS(arrayDtp, UnpackArrayDType) && !allConstant && isConcat)) { // If arrayDtp is an unpacked array and item is not constant, - // the number of elemnt cannot be determined here as the dtype of each element - // is not set yet. V3Slice checks for such cases. + // the number of elements cannot be determined here as the dtype of each + // element is not set yet. V3Slice checks for such cases. nodep->v3error("Assignment pattern missed initializing elements: " << ent); } } else { @@ -7855,14 +7855,18 @@ class WidthVisitor final : public VNVisitor { if (AstConcat* lhsp = VN_CAST(nodep->lhsp(), Concat)) { patConcatConvertRecurse(patternp, lhsp); } else { - patternp->addItemsp(new AstPatMember{nodep->lhsp()->fileline(), - nodep->lhsp()->unlinkFrBack(), nullptr, nullptr}); + AstPatMember* const newp = new AstPatMember{ + nodep->lhsp()->fileline(), nodep->lhsp()->unlinkFrBack(), nullptr, nullptr}; + newp->isConcat(true); + patternp->addItemsp(newp); } if (AstConcat* rhsp = VN_CAST(nodep->rhsp(), Concat)) { patConcatConvertRecurse(patternp, rhsp); } else { - patternp->addItemsp(new AstPatMember{nodep->rhsp()->fileline(), - nodep->rhsp()->unlinkFrBack(), nullptr, nullptr}); + AstPatMember* const newp = new AstPatMember{ + nodep->rhsp()->fileline(), nodep->rhsp()->unlinkFrBack(), nullptr, nullptr}; + newp->isConcat(true); + patternp->addItemsp(newp); } } diff --git a/test_regress/t/t_unpacked_concat_bad.out b/test_regress/t/t_unpacked_concat_bad.out index 6b736d415..051187a46 100644 --- a/test_regress/t/t_unpacked_concat_bad.out +++ b/test_regress/t/t_unpacked_concat_bad.out @@ -3,4 +3,8 @@ 12 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}}; | ^ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: t/t_unpacked_concat_bad.v:12:46: Assignment pattern missed initializing elements: 0 + : ... note: In instance 't' + 12 | localparam bit_int_t count_bits [1:0] = {2{$bits(count_t)}}; + | ^ %Error: Exiting due to diff --git a/test_regress/t/t_unpacked_concat_bad3.out b/test_regress/t/t_unpacked_concat_bad3.out index 4bd30ce0c..f106250c0 100644 --- a/test_regress/t/t_unpacked_concat_bad3.out +++ b/test_regress/t/t_unpacked_concat_bad3.out @@ -1,4 +1,9 @@ -%Error: Internal Error: t/t_unpacked_concat_bad3.v:9:41: ../V3EmitCConstInit.h:#: Missing array init element +%Error: t/t_unpacked_concat_bad3.v:9:41: Assignment pattern missed initializing elements: 3 + : ... note: In instance 't' 9 | localparam logic [7:0] TOO_FEW [5] = '{0, 1, 2**8-1}; | ^~ - ... See the manual at https://verilator.org/verilator_doc.html for more assistance. +%Error: t/t_unpacked_concat_bad3.v:9:41: Assignment pattern missed initializing elements: 4 + : ... note: In instance 't' + 9 | localparam logic [7:0] TOO_FEW [5] = '{0, 1, 2**8-1}; + | ^~ +%Error: Exiting due to From 2284ada72304b83587b774510c65d2fd31f281b5 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 18:56:36 -0500 Subject: [PATCH 115/171] Tests: Interface-to-wire (#5649 test partial) --- test_regress/t/t_iface_wire_bad.out | 5 +++++ test_regress/t/t_iface_wire_bad.py | 16 ++++++++++++++++ test_regress/t/t_iface_wire_bad.v | 17 +++++++++++++++++ test_regress/t/t_iface_wire_bad_param.out | 5 +++++ test_regress/t/t_iface_wire_bad_param.py | 16 ++++++++++++++++ test_regress/t/t_iface_wire_bad_param.v | 17 +++++++++++++++++ 6 files changed, 76 insertions(+) create mode 100644 test_regress/t/t_iface_wire_bad.out create mode 100755 test_regress/t/t_iface_wire_bad.py create mode 100644 test_regress/t/t_iface_wire_bad.v create mode 100644 test_regress/t/t_iface_wire_bad_param.out create mode 100755 test_regress/t/t_iface_wire_bad_param.py create mode 100644 test_regress/t/t_iface_wire_bad_param.v diff --git a/test_regress/t/t_iface_wire_bad.out b/test_regress/t/t_iface_wire_bad.out new file mode 100644 index 000000000..f0d4767da --- /dev/null +++ b/test_regress/t/t_iface_wire_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_iface_wire_bad.v:16:20: Operator ASSIGNW expected non-interface on Assign RHS but 'a__Viftop' is an interface. + : ... note: In instance 't' + 16 | wire wbad = sub.a; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_iface_wire_bad.py b/test_regress/t/t_iface_wire_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_iface_wire_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_iface_wire_bad.v b/test_regress/t/t_iface_wire_bad.v new file mode 100644 index 000000000..5a01c4e64 --- /dev/null +++ b/test_regress/t/t_iface_wire_bad.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface Ifc; +endinterface + +module Sub; + Ifc a(); +endmodule + +module t; + Sub sub(); + wire wbad = sub.a; +endmodule diff --git a/test_regress/t/t_iface_wire_bad_param.out b/test_regress/t/t_iface_wire_bad_param.out new file mode 100644 index 000000000..ff54bf85d --- /dev/null +++ b/test_regress/t/t_iface_wire_bad_param.out @@ -0,0 +1,5 @@ +%Error: Internal Error: t/t_iface_wire_bad_param.v:16:20: ../V3Broken.cpp:#: Broken link in node (or something without maybePointedTo): 'm_varp && !m_varp->brokeExists()' @ ./V3Ast__gen_impl.h:# + : ... note: In instance 't' + 16 | wire wbad = sub.a; + | ^ + ... See the manual at https://verilator.org/verilator_doc.html for more assistance. diff --git a/test_regress/t/t_iface_wire_bad_param.py b/test_regress/t/t_iface_wire_bad_param.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_iface_wire_bad_param.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_iface_wire_bad_param.v b/test_regress/t/t_iface_wire_bad_param.v new file mode 100644 index 000000000..d814123ea --- /dev/null +++ b/test_regress/t/t_iface_wire_bad_param.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface Ifc; +endinterface + +module Sub #(parameter P); + Ifc a(); +endmodule + +module t; + Sub #(0) sub(); + wire wbad = sub.a; +endmodule From 5021989cb6d688cd2fb86d5c8f95f2a0bd036ec8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 19:04:31 -0500 Subject: [PATCH 116/171] Tests: Rename interface-to-wire (#5649 test partial) --- test_regress/t/t_iface_wire_bad.out | 5 ----- test_regress/t/t_iface_wire_bad_param.out | 5 ----- test_regress/t/t_interface_wire_bad.out | 5 +++++ .../t/{t_iface_wire_bad.py => t_interface_wire_bad.py} | 0 .../t/{t_iface_wire_bad.v => t_interface_wire_bad.v} | 1 + test_regress/t/t_interface_wire_bad_param.out | 5 +++++ ...iface_wire_bad_param.py => t_interface_wire_bad_param.py} | 0 ...t_iface_wire_bad_param.v => t_interface_wire_bad_param.v} | 1 + 8 files changed, 12 insertions(+), 10 deletions(-) delete mode 100644 test_regress/t/t_iface_wire_bad.out delete mode 100644 test_regress/t/t_iface_wire_bad_param.out create mode 100644 test_regress/t/t_interface_wire_bad.out rename test_regress/t/{t_iface_wire_bad.py => t_interface_wire_bad.py} (100%) rename test_regress/t/{t_iface_wire_bad.v => t_interface_wire_bad.v} (94%) create mode 100644 test_regress/t/t_interface_wire_bad_param.out rename test_regress/t/{t_iface_wire_bad_param.py => t_interface_wire_bad_param.py} (100%) rename test_regress/t/{t_iface_wire_bad_param.v => t_interface_wire_bad_param.v} (95%) diff --git a/test_regress/t/t_iface_wire_bad.out b/test_regress/t/t_iface_wire_bad.out deleted file mode 100644 index f0d4767da..000000000 --- a/test_regress/t/t_iface_wire_bad.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error: t/t_iface_wire_bad.v:16:20: Operator ASSIGNW expected non-interface on Assign RHS but 'a__Viftop' is an interface. - : ... note: In instance 't' - 16 | wire wbad = sub.a; - | ^ -%Error: Exiting due to diff --git a/test_regress/t/t_iface_wire_bad_param.out b/test_regress/t/t_iface_wire_bad_param.out deleted file mode 100644 index ff54bf85d..000000000 --- a/test_regress/t/t_iface_wire_bad_param.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error: Internal Error: t/t_iface_wire_bad_param.v:16:20: ../V3Broken.cpp:#: Broken link in node (or something without maybePointedTo): 'm_varp && !m_varp->brokeExists()' @ ./V3Ast__gen_impl.h:# - : ... note: In instance 't' - 16 | wire wbad = sub.a; - | ^ - ... See the manual at https://verilator.org/verilator_doc.html for more assistance. diff --git a/test_regress/t/t_interface_wire_bad.out b/test_regress/t/t_interface_wire_bad.out new file mode 100644 index 000000000..c792bf9b6 --- /dev/null +++ b/test_regress/t/t_interface_wire_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_interface_wire_bad.v:17:20: Operator ASSIGNW expected non-interface on Assign RHS but 'a__Viftop' is an interface. + : ... note: In instance 't' + 17 | wire wbad = sub.a; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_iface_wire_bad.py b/test_regress/t/t_interface_wire_bad.py similarity index 100% rename from test_regress/t/t_iface_wire_bad.py rename to test_regress/t/t_interface_wire_bad.py diff --git a/test_regress/t/t_iface_wire_bad.v b/test_regress/t/t_interface_wire_bad.v similarity index 94% rename from test_regress/t/t_iface_wire_bad.v rename to test_regress/t/t_interface_wire_bad.v index 5a01c4e64..d4401b6e1 100644 --- a/test_regress/t/t_iface_wire_bad.v +++ b/test_regress/t/t_interface_wire_bad.v @@ -13,5 +13,6 @@ endmodule module t; Sub sub(); + // Issue #5649 wire wbad = sub.a; endmodule diff --git a/test_regress/t/t_interface_wire_bad_param.out b/test_regress/t/t_interface_wire_bad_param.out new file mode 100644 index 000000000..7aebb6752 --- /dev/null +++ b/test_regress/t/t_interface_wire_bad_param.out @@ -0,0 +1,5 @@ +%Error: Internal Error: t/t_interface_wire_bad_param.v:17:20: ../V3Broken.cpp:#: Broken link in node (or something without maybePointedTo): 'm_varp && !m_varp->brokeExists()' @ ./V3Ast__gen_impl.h:# + : ... note: In instance 't' + 17 | wire wbad = sub.a; + | ^ + ... See the manual at https://verilator.org/verilator_doc.html for more assistance. diff --git a/test_regress/t/t_iface_wire_bad_param.py b/test_regress/t/t_interface_wire_bad_param.py similarity index 100% rename from test_regress/t/t_iface_wire_bad_param.py rename to test_regress/t/t_interface_wire_bad_param.py diff --git a/test_regress/t/t_iface_wire_bad_param.v b/test_regress/t/t_interface_wire_bad_param.v similarity index 95% rename from test_regress/t/t_iface_wire_bad_param.v rename to test_regress/t/t_interface_wire_bad_param.v index d814123ea..5399bbd9a 100644 --- a/test_regress/t/t_iface_wire_bad_param.v +++ b/test_regress/t/t_interface_wire_bad_param.v @@ -13,5 +13,6 @@ endmodule module t; Sub #(0) sub(); + // Issue #5649 wire wbad = sub.a; endmodule From a51e26e62d6d40118026564cb30df246f00cfc53 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 20:09:05 -0500 Subject: [PATCH 117/171] Internals: Some V3LinkCells debug improvements. No functional change. --- src/V3LinkCells.cpp | 19 +++++++++++-------- src/V3LinkDot.cpp | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index becf8b566..718541db7 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -56,7 +56,7 @@ public: , m_modp{modp} {} ~LinkCellsVertex() override = default; AstNodeModule* modp() const VL_MT_STABLE { return m_modp; } - string name() const override VL_MT_STABLE { return modp()->name(); } + string name() const override VL_MT_STABLE { return cvtToHex(modp()) + ' ' + modp()->name(); } FileLine* fileline() const override { return modp()->fileline(); } // Recursive modules get space for maximum recursion uint32_t rankAdder() const override { @@ -124,6 +124,10 @@ class LinkCellsVisitor final : public VNVisitor { if (!nodep->user1p()) nodep->user1p(new LinkCellsVertex{&m_graph, nodep}); return nodep->user1u().toGraphVertex(); } + void newEdge(V3GraphVertex* fromp, V3GraphVertex* top, int weight, bool cuttable) { + UINFO(9, "newEdge " << fromp->name() << " -> " << top->name() << endl); + new V3GraphEdge{&m_graph, fromp, top, weight, cuttable}; + } AstNodeModule* findModuleSym(const string& modName) { const VSymEnt* const foundp = m_mods.rootp()->findIdFallback(modName); @@ -184,7 +188,7 @@ class LinkCellsVisitor final : public VNVisitor { VL_RESTORER(m_modp); { // For nested modules/classes, child below parent - if (m_modp) new V3GraphEdge{&m_graph, vertex(m_modp), vertex(nodep), 1}; + if (m_modp) newEdge(vertex(m_modp), vertex(nodep), 1, false); // m_modp = nodep; UINFO(4, "Link Module: " << nodep << endl); @@ -216,7 +220,7 @@ class LinkCellsVisitor final : public VNVisitor { // Put under a fake vertex so that the graph ranking won't indicate // this is a top level module if (!m_libVertexp) m_libVertexp = new LibraryVertex{&m_graph}; - new V3GraphEdge{&m_graph, m_libVertexp, vertex(nodep), 1, false}; + newEdge(m_libVertexp, vertex(nodep), 1, false); } // Note AstBind also has iteration on cells iterateChildren(nodep); @@ -233,7 +237,7 @@ class LinkCellsVisitor final : public VNVisitor { if (modp) { if (VN_IS(modp, Iface)) { // Track module depths, so can sort list from parent down to children - new V3GraphEdge{&m_graph, vertex(m_modp), vertex(modp), 1, false}; + newEdge(vertex(m_modp), vertex(modp), 1, false); if (!nodep->cellp()) nodep->ifacep(VN_AS(modp, Iface)); } else if (VN_IS(modp, NotFoundModule)) { // Will error out later } else { @@ -279,7 +283,7 @@ class LinkCellsVisitor final : public VNVisitor { return; } } - new V3GraphEdge{&m_graph, vertex(m_modp), vertex(nodep->packagep()), 1, false}; + newEdge(vertex(m_modp), vertex(nodep->packagep()), 1, false); } void visit(AstBind* nodep) override { @@ -349,8 +353,7 @@ class LinkCellsVisitor final : public VNVisitor { // user1 etc will retain its pre-clone value cellmodp->user2p(otherModp); v3Global.rootp()->addModulesp(otherModp); - new V3GraphEdge{&m_graph, vertex(cellmodp), vertex(otherModp), 1, - false}; + newEdge(vertex(cellmodp), vertex(otherModp), 1, false); } cellmodp = otherModp; nodep->modp(cellmodp); @@ -363,7 +366,7 @@ class LinkCellsVisitor final : public VNVisitor { } else { // Non-recursive // Track module depths, so can sort list from parent down to children nodep->modp(cellmodp); - new V3GraphEdge{&m_graph, vertex(m_modp), vertex(cellmodp), 1, false}; + newEdge(vertex(m_modp), vertex(cellmodp), 1, false); } } } diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index dceba9722..304bd4529 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3134,7 +3134,6 @@ class LinkDotResolveVisitor final : public VNVisitor { if (m_ds.m_dotText != "") m_ds.m_dotText += "." + nodep->name(); ok = m_ds.m_dotPos == DP_SCOPE || m_ds.m_dotPos == DP_FIRST; } else if (const AstNodeFTask* const ftaskp = VN_CAST(foundp->nodep(), NodeFTask)) { - if (!ftaskp->isFunction() || ftaskp->classMethod()) { ok = m_ds.m_dotPos == DP_NONE; if (ok) { From 2d71d66cf5d2cbf8a70a40eb2bdfe1155ea55c03 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 22:17:18 -0500 Subject: [PATCH 118/171] Commentary --- src/V3AstNodes.cpp | 2 +- src/V3Error.h | 16 +++++++++++----- src/V3LinkDot.cpp | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 7f4c57e0e..62596a32d 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -794,7 +794,7 @@ const AstNodeDType* AstNodeDType::skipRefIterp(bool skipConst, bool skipEnum) co nodep = subp; continue; } else { - v3fatalSrc("Typedef not linked"); + nodep->v3fatalSrc(nodep->prettyTypeName() << " not linked to type"); return nullptr; } } diff --git a/src/V3Error.h b/src/V3Error.h index d0a2bf77f..62cb9af52 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -564,9 +564,9 @@ void v3errorEndFatal(std::ostringstream& sstr) #define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg) #define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg) #define v3fatal(msg) v3warnCodeFatal(V3ErrorCode::EC_FATAL, msg) -// Use this instead of fatal() if message gets suppressed with --quiet-exit +// Fatal exit; used instead of fatal() if message gets suppressed with --quiet-exit #define v3fatalExit(msg) v3warnCodeFatal(V3ErrorCode::EC_FATALEXIT, msg) -// Use this instead of fatal() to mention the source code line. +// Fatal exit; used instead of fatal() to mention the source code line #define v3fatalSrc(msg) \ v3errorEndFatal(v3errorBuildMessage( \ V3Error::v3errorPrepFileLine(V3ErrorCode::EC_FATALSRC, __FILE__, __LINE__), msg)) @@ -574,6 +574,10 @@ void v3errorEndFatal(std::ostringstream& sstr) #define v3fatalStatic(msg) \ ::v3errorEndFatal(v3errorBuildMessage(V3Error::v3errorPrep(V3ErrorCode::EC_FATAL), msg)) +/// Print a message when debug() >= level. stmsg is stream; e.g. use as '"foo=" << foo' +// +// Requires debug() function to exist in current scope, to hack this in temporarily: +// auto debug = []() -> bool { return V3Error::debugDefault(); }; #define UINFO(level, stmsg) \ do { \ if (VL_UNCOVERABLE(debug() >= (level))) { \ @@ -585,6 +589,7 @@ void v3errorEndFatal(std::ostringstream& sstr) if (VL_UNCOVERABLE(debug() >= (level))) { std::cout << stmsg; } \ } while (false) +/// Compile statements only when debug build #ifdef VL_DEBUG #define UDEBUGONLY(stmts) \ do { stmts } while (false) @@ -595,12 +600,12 @@ void v3errorEndFatal(std::ostringstream& sstr) } while (false) #endif -// Assertion without object, generally UOBJASSERT preferred +/// Assert without error location, generally UASSERT_OBJ preferred #define UASSERT(condition, stmsg) \ do { \ if (VL_UNCOVERABLE(!(condition))) v3fatalSrc(stmsg); \ } while (false) -// Assertion with object +/// Assert with object to provide error location #define UASSERT_OBJ(condition, obj, stmsg) \ do { \ if (VL_UNCOVERABLE(!(condition))) (obj)->v3fatalSrc(stmsg); \ @@ -614,7 +619,7 @@ void v3errorEndFatal(std::ostringstream& sstr) V3Error::vlAbort(); \ } \ } while (false) -// Check self test values for expected value. Safe from side-effects. +/// Check self test values for expected value. Safe from side-effects. // Type argument can be removed when go to C++11 (use auto). #define UASSERT_SELFTEST(Type, got, exp) \ do { \ @@ -625,6 +630,7 @@ void v3errorEndFatal(std::ostringstream& sstr) << g << " expected=" << e); \ } while (false) +// Error that call not supported; only for some Ast functions #define V3ERROR_NA \ do { \ v3error("Internal: Unexpected Call"); \ diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 304bd4529..95a200463 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1692,7 +1692,6 @@ public: LinkDotFindVisitor(AstNetlist* rootp, LinkDotState* statep) : m_statep{statep} { UINFO(4, __FUNCTION__ << ": " << endl); - iterate(rootp); } ~LinkDotFindVisitor() override = default; @@ -4063,7 +4062,8 @@ class LinkDotResolveVisitor final : public VNVisitor { const AstClass* const clsp = VN_CAST(cpackagerefp->classOrPackageNodep(), Class); if (clsp && clsp->isParameterized()) { // Unable to link before the instantiation of parameter classes. - // The class reference node has to be visited to properly link parameters. + // The class reference node still has to be visited now to later link + // parameters. iterate(cpackagep); return; } From 7a04a5b9a8d8cece01ea934625eb556ac00d197a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 30 Nov 2024 22:55:16 -0500 Subject: [PATCH 119/171] Internals: Refactor symIterate functions. No functional change intended --- src/V3LinkDot.cpp | 82 ++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 95a200463..bde24b439 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2448,17 +2448,32 @@ class LinkDotResolveVisitor final : public VNVisitor { // A class reference might be to a class that is later in Ast due to // e.g. parmaeterization or referring to a "class (type T) extends T" // Resolve it so later Class:: references into its base classes work - VL_RESTORER(m_ds); - VSymEnt* const srcp = m_statep->getNodeSym(nodep); - m_ds.init(srcp); - iterate(nodep); + symIterateNull(nodep, m_statep->getNodeSym(nodep)); } + void updateVarUse(AstVar* nodep) { // Avoid dotted.PARAM false positive when in a parameter block // that is if ()'ed off by same dotted name as another block if (nodep && nodep->isParam()) nodep->usedParam(true); } + void symIterateChildren(AstNode* nodep, VSymEnt* symp) { + // Iterate children, changing to given context, with restore to old context + VL_RESTORER(m_ds); + VL_RESTORER(m_curSymp); + m_curSymp = symp; + m_ds.init(m_curSymp); + iterateChildren(nodep); + } + void symIterateNull(AstNode* nodep, VSymEnt* symp) { + // Iterate node, changing to given context, with restore to old context + VL_RESTORER(m_ds); + VL_RESTORER(m_curSymp); + m_curSymp = symp; + m_ds.init(m_curSymp); + iterateNull(nodep); + } + #define LINKDOT_VISIT_START() \ VL_RESTORER(m_indent); \ ++m_indent; @@ -2494,14 +2509,12 @@ class LinkDotResolveVisitor final : public VNVisitor { void visit(AstScope* nodep) override { LINKDOT_VISIT_START(); UINFO(8, indent() << "visit " << nodep << endl); + checkNoDot(nodep); VL_RESTORER(m_modSymp); VL_RESTORER(m_curSymp); - { - checkNoDot(nodep); - m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getScopeSym(nodep); - iterateChildren(nodep); - m_ds.m_dotSymp = m_curSymp = m_modSymp = nullptr; - } + m_ds.m_dotSymp = m_curSymp = m_modSymp = m_statep->getScopeSym(nodep); + iterateChildren(nodep); + m_ds.m_dotSymp = m_curSymp = m_modSymp = nullptr; } void visit(AstCellInline* nodep) override { LINKDOT_VISIT_START(); @@ -2670,6 +2683,8 @@ class LinkDotResolveVisitor final : public VNVisitor { } else { if (m_statep->forPrimary() && m_extendsParam.find(classp) != m_extendsParam.end()) { + UINFO(9, indent() << "deferring until post-V3Param: " << nodep->lhsp() + << endl); m_ds.m_unresolvedClass = true; } else { const auto baseClassp = cextp->classp(); @@ -2696,6 +2711,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } if (m_statep->forPrimary() && isParamedClassRef(nodep->lhsp())) { // Dots of paramed classes will be linked after deparameterization + UINFO(9, indent() << "deferring until post-V3Param: " << nodep->lhsp() << endl); m_ds.m_unresolvedClass = true; } if (m_ds.m_unresolvedCell @@ -3024,6 +3040,8 @@ class LinkDotResolveVisitor final : public VNVisitor { refp->dotted(dotted.substr(0, pos)); newp = refp; } else { + UINFO(9, indent() + << "deferring until post-V3Param: " << refp << endl); newp = new AstUnlinkedRef{nodep->fileline(), refp, refp->name(), m_ds.m_unlinkedScopep->unlinkFrBack()}; m_ds.m_unlinkedScopep = nullptr; @@ -3475,9 +3493,7 @@ class LinkDotResolveVisitor final : public VNVisitor { if (m_ds.m_dotPos != DP_MEMBER || nodep->name() != "randomize") { // Visit arguments at the beginning. // They may be visitted even if the current node can't be linked now. - VL_RESTORER(m_ds); - m_ds.init(m_curSymp); - iterateChildren(nodep); + symIterateChildren(nodep, m_curSymp); } if (m_ds.m_super) { @@ -3732,16 +3748,10 @@ class LinkDotResolveVisitor final : public VNVisitor { m_ds.m_unresolvedCell = true; // And pass up m_ds.m_dotText } - // Pass dot state down to fromp() + // Pass dot state down to only fromp() iterateAndNextNull(nodep->fromp()); - { - VL_RESTORER(m_ds); - { - m_ds.init(m_curSymp); - iterateAndNextNull(nodep->bitp()); - iterateAndNextNull(nodep->attrp()); - } - } + symIterateNull(nodep->bitp(), m_curSymp); + symIterateNull(nodep->attrp(), m_curSymp); if (m_ds.m_unresolvedCell && (m_ds.m_dotPos == DP_SCOPE || m_ds.m_dotPos == DP_FIRST)) { AstNodeExpr* const exprp = nodep->bitp()->unlinkFrBack(); AstCellArrayRef* const newp @@ -3763,12 +3773,8 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } iterateAndNextNull(nodep->fromp()); - VL_RESTORER(m_ds); - { - m_ds.init(m_curSymp); - iterateAndNextNull(nodep->rhsp()); - iterateAndNextNull(nodep->thsp()); - } + symIterateNull(nodep->rhsp(), m_curSymp); + symIterateNull(nodep->thsp(), m_curSymp); if (nodep->attrp()) { AstNode* const attrp = nodep->attrp()->unlinkFrBack(); @@ -3792,15 +3798,15 @@ class LinkDotResolveVisitor final : public VNVisitor { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); checkNoDot(nodep); - VL_RESTORER(m_curSymp); { + VL_RESTORER(m_curSymp); + VL_RESTORER(m_ds); if (nodep->name() != "") { m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); UINFO(5, indent() << "cur=se" << cvtToHex(m_curSymp) << endl); } iterateChildren(nodep); } - m_ds.m_dotSymp = VL_RESTORER_PREV(m_curSymp); UINFO(5, indent() << "cur=se" << cvtToHex(m_curSymp) << endl); } void visit(AstNodeFTask* nodep) override { @@ -3849,25 +3855,15 @@ class LinkDotResolveVisitor final : public VNVisitor { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); checkNoDot(nodep); - VL_RESTORER(m_curSymp); - { - m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); - iterateChildren(nodep); - } - m_ds.m_dotSymp = VL_RESTORER_PREV(m_curSymp); + symIterateChildren(nodep, m_statep->getNodeSym(nodep)); } void visit(AstWith* nodep) override { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); checkNoDot(nodep); - VL_RESTORER(m_curSymp); VL_RESTORER(m_inWith); - { - m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); - m_inWith = true; - iterateChildren(nodep); - } - m_ds.m_dotSymp = VL_RESTORER_PREV(m_curSymp); + m_inWith = true; + symIterateChildren(nodep, m_statep->getNodeSym(nodep)); } void visit(AstLambdaArgRef* nodep) override { LINKDOT_VISIT_START(); From 611567c3854bba6b2b287c68310246c7bf15b651 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 10:25:09 -0500 Subject: [PATCH 120/171] Internals: add make format-c/format-py. No functional change. --- Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile.in b/Makefile.in index a9484494d..ae88cbcf4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -452,13 +452,13 @@ analyzer-include: scan-build $(MAKE) -k examples format: - $(MAKE) -j 4 clang-format yapf format-exec + $(MAKE) -j 4 format-c format-py format-exec CLANGFORMAT = clang-format-14 CLANGFORMAT_FLAGS = -i CLANGFORMAT_FILES = $(CHECK_CPP) $(CHECK_H) $(CHECK_YL) test_regress/t/*.c* test_regress/t/*.h -clang-format: +format-c clang-format: @$(CLANGFORMAT) --version | egrep 14.0 > /dev/null \ || echo "*** You are not using clang-format-14, indents may differ from master's ***" $(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES) @@ -518,7 +518,7 @@ PY_TEST_FILES = \ YAPF = yapf3 YAPF_FLAGS = -i --parallel -yapf: +format-py yapf: $(YAPF) $(YAPF_FLAGS) $(PY_FILES) GERSEMI = gersemi From 9ec5413d33d6a0de22d21f3a30caa567eef8e22d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 10:27:05 -0500 Subject: [PATCH 121/171] Tests: Cleaner error summaries --- test_regress/driver.py | 63 ++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/test_regress/driver.py b/test_regress/driver.py index cd7015d23..75ded4d44 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -449,7 +449,7 @@ class Runner: else: error_msg = test.errors if test.errors else test.errors_keep_going test.oprint("FAILED: " + error_msg) - makecmd = VtOs.getenv_def('VERILATOR_MAKE', os.environ['MAKE']) + " &&" + makecmd = VtOs.getenv_def('VERILATOR_MAKE', os.environ['MAKE'] + "&&") upperdir = 'test_regress/' if re.search(r'test_regress', os.getcwd()) else '' self.fail_msgs.append("\t#" + test.soprint("%Error: " + error_msg) + "\t\t" + makecmd + " " + upperdir + test.py_filename + ' ' + @@ -603,6 +603,7 @@ class VlTest: self.running_id = running_id self.scenario = scenario + self._force_pass = False self._have_solver_called = False self._inputs = {} self._ok = False @@ -814,6 +815,8 @@ class VlTest: """Called from tests as: error("Reason message") Newline is optional. Only first line is passed to summaries Throws a VtErrorException, so rest of testing is not executed""" + if self._force_pass: + return message = message.rstrip() + "\n" print("%Warning: " + self.scenario + "/" + self.name + ": " + message, file=sys.stderr, @@ -826,7 +829,7 @@ class VlTest: def error_keep_going(self, message: str) -> None: """Called from tests as: error_keep_going("Reason message") Newline is optional. Only first line is passed to summaries""" - if self._quit: + if self._quit or self._force_pass: return message = message.rstrip() + "\n" print("%Warning: " + self.scenario + "/" + self.name + ": " + message, @@ -1710,6 +1713,9 @@ class VlTest: got = proc.stdout.readinto(rawbuf) if got: data = rawbuf[0:got] + if re.search(r'--debug-exit-uvm23: Exiting', str(data)): + self._force_pass = True + print("EXIT: " + str(data)) if tee: sys.stdout.write(data.decode('latin-1')) if Args.interactive_debugger: @@ -1741,20 +1747,12 @@ class VlTest: print("driver: Leaving directory '" + os.path.abspath(entering) + "'") if not fails and status: - firstline = "" - if logfile: - with open(logfile, 'r', encoding="utf8") as fh: - for line in fh: - line = line.rstrip() - if re.match(r'^- ', line): # Debug message - continue - firstline = line - break - self.error("Exec of " + cmd[0] + " failed: " + firstline) + firstline = self._error_log_summary(logfile) + self.error("Exec of " + self._error_cmd_simplify(cmd) + " failed: " + firstline) if fails and status: print("(Exec expected to fail, and did.)") if fails and not status: - self.error("Exec of " + cmd[0] + " ok, but expected to fail") + self.error("Exec of " + self._error_cmd_simplify(cmd) + " ok, but expected to fail") if self.errors or self._skips: return False @@ -1793,17 +1791,34 @@ class VlTest: # Little utilities @staticmethod - def _try_regex(text: str, regex) -> None: - # Try to eval a regexp - # Returns: - # 1 if $text ~= /$regex/ms - # 0 if no match - # -1 if $regex is invalid, doesn't compile - try: - m = re.search(regex, text) - return 1 if m else 0 - except re.error: - return -1 + def _error_cmd_simplify(cmd: list) -> str: + if cmd[0] == "perl" and re.search(r'/bin/verilator', cmd[1]): + return "verilator" + return cmd[0] + + def _error_log_summary(self, filename: str) -> str: + size = "" + if False: # Show test size for fault grading # pylint: disable=using-constant-test + if self.top_filename and os.path.exists(self.top_filename): + size = "(Test " + str(os.stat(self.top_filename).st_size) + " B) " + if not filename: + return size + firstline = "" + with open(filename, 'r', encoding="utf8") as fh: + lineno = 0 + for line in fh: + lineno += 1 + if lineno > 100: + break + line = line.rstrip() + if re.match(r'^- ', line): # Debug message + continue + if not firstline: + firstline = line + if (re.search(r'error|warn', line, re.IGNORECASE) + and not re.search(r'-Werror', line)): + return size + line + return size + firstline def _make_main(self, timing_loop: bool) -> None: if timing_loop and self.sc: From b0f898cec87a2bd772d7811c462b1e2abf35ca47 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 11:35:00 -0500 Subject: [PATCH 122/171] Internals: Determine needing verilated_std without symbol table --- include/verilated_std.sv | 3 +++ src/Makefile_obj.in | 4 +++- src/V3ParseImp.cpp | 30 ++++++++++++++++++++++-------- src/V3ParseImp.h | 1 + test_regress/t/t_dump_json.out | 16 ++++++++-------- test_regress/t/t_std_identifier.py | 2 +- 6 files changed, 38 insertions(+), 18 deletions(-) diff --git a/include/verilated_std.sv b/include/verilated_std.sv index 8a1e2541c..dfe8b9ab6 100644 --- a/include/verilated_std.sv +++ b/include/verilated_std.sv @@ -21,6 +21,9 @@ /// It is only for internal use. /// //************************************************************************* +// +// The following keywords from this file are hardcoded for detection in the parser: +// "mailbox", "process", "randomize", "semaphore", "std" // verilator lint_off DECLFILENAME // verilator lint_off TIMESCALEMOD diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index adfcb2215..291bb88c9 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -142,6 +142,8 @@ BISONPRE = $(srcdir)/bisonpre FLEXFIX = $(srcdir)/flexfix VLCOVGEN = $(srcdir)/vlcovgen +# BISON_DEBUG = -Wcounterexamples + ###################################################################### # CCACHE flags (via environment as no command line option available) CCACHE_SLOPPINESS ?= pch_defines,time_macros @@ -417,7 +419,7 @@ V3ParseBison.h: V3ParseBison.c # Have only one output file in this rule to prevent parallel make issues V3ParseBison.c: verilog.y $(BISONPRE) @echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer." - $(PYTHON3) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $< + $(PYTHON3) $(BISONPRE) --yacc ${YACC} -d -v -o V3ParseBison.c $(BISON_DEBUG) $< V3Lexer_pregen.yy.cpp: verilog.l V3ParseBison.h $(HEADERS) ${LEX} --version diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 0b98a6c8f..451e08982 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -70,6 +70,25 @@ V3ParseImp::~V3ParseImp() { //###################################################################### // Parser utility methods +void V3ParseImp::importIfInStd(FileLine* fileline, const string& id) { + // Keywords that auto-import to require use of verilated_std.vh. + // OK if overly sensitive; will over-import and keep std:: around + // longer than migt otherwise. + if (v3Global.usesStdPackage()) return; // Run once then short-circuit + const bool identifierImportsStd = (id == "mailbox" || id == "process" || id == "randomize" + || id == "semaphore" || id == "std"); + if (!identifierImportsStd) return; + // Ignore Std:: used inside verilated_std.vh itself + if (fileline->filename() == V3Options::getStdPackagePath()) return; + if (AstPackage* const stdpkgp + = v3Global.rootp()->stdPackagep()) { // else e.g. --no-std-package + UINFO(9, "import and keep std:: for " << fileline << "\n"); + AstPackageImport* const impp = new AstPackageImport{stdpkgp->fileline(), stdpkgp, "*"}; + unitPackage(stdpkgp->fileline())->addStmtsp(impp); + v3Global.setUsesStdPackage(); + } +} + void V3ParseImp::lexPpline(const char* textp) { // Handle lexer `line directive // FileLine* const prevFl = lexFileline(); @@ -647,6 +666,9 @@ void V3ParseImp::tokenPipelineSym() { // Note above sometimes converts yGLOBAL to a yaID__LEX tokenPipeline(); // sets yylval int token = yylval.token; + if (token == yaID__LEX || token == yaID__CC || token == yaID__aTYPE) { + importIfInStd(yylval.fl, *(yylval.strp)); + } if (token == yaID__LEX || token == yaID__CC) { const VSymEnt* foundp; if (const VSymEnt* const look_underp = V3ParseImp::parsep()->symp()->nextId()) { @@ -669,12 +691,6 @@ void V3ParseImp::tokenPipelineSym() { VSymEnt* const stdsymp = stdpkgp->user4u().toSymEnt(); foundp = stdsymp->findIdFallback(*(yylval.strp)); } - if (foundp && !v3Global.usesStdPackage()) { - AstPackageImport* const impp - = new AstPackageImport{stdpkgp->fileline(), stdpkgp, "*"}; - unitPackage(stdpkgp->fileline())->addStmtsp(impp); - v3Global.setUsesStdPackage(); - } } if (foundp) { AstNode* const scp = foundp->nodep(); @@ -692,8 +708,6 @@ void V3ParseImp::tokenPipelineSym() { } else { token = yaID__ETC; } - } else if (!m_afterColonColon && *(yylval.strp) == "std") { - v3Global.setUsesStdPackage(); } } else { // Not found yylval.scp = nullptr; diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 82e8e4fcb..1afbf98fe 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -309,6 +309,7 @@ private: void preprocDumps(std::ostream& os); void lexFile(const string& modname) VL_MT_DISABLED; void yylexReadTok() VL_MT_DISABLED; + void importIfInStd(FileLine* fileline, const string& id); void tokenPull() VL_MT_DISABLED; void tokenPipeline() VL_MT_DISABLED; // Internal; called from tokenToBison int tokenPipelineId(int token) VL_MT_DISABLED; diff --git a/test_regress/t/t_dump_json.out b/test_regress/t/t_dump_json.out index ac99ae1cd..602123ff9 100644 --- a/test_regress/t/t_dump_json.out +++ b/test_regress/t/t_dump_json.out @@ -519,14 +519,14 @@ "miscsp": [ {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(HI)", "typesp": [ - {"type":"BASICDTYPE","name":"integer","addr":"(II)","loc":"d,31:27,31:28","dtypep":"(II)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"d,33:32,33:33","dtypep":"(L)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(UE)","loc":"d,50:22,50:24","dtypep":"(UE)","keyword":"logic","generic":true,"rangep": []}, - {"type":"VOIDDTYPE","name":"","addr":"(HI)","loc":"d,51:21,51:30","dtypep":"(HI)","generic":false}, - {"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"d,125:22,125:23","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(JI)","loc":"d,127:22,127:23","dtypep":"(JI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(KI)","loc":"d,162:17,162:56","dtypep":"(KI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"string","addr":"(BG)","loc":"d,162:10,162:16","dtypep":"(BG)","keyword":"string","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"integer","addr":"(II)","loc":"d,34:27,34:28","dtypep":"(II)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(L)","loc":"d,36:32,36:33","dtypep":"(L)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(UE)","loc":"d,53:22,53:24","dtypep":"(UE)","keyword":"logic","generic":true,"rangep": []}, + {"type":"VOIDDTYPE","name":"","addr":"(HI)","loc":"d,54:21,54:30","dtypep":"(HI)","generic":false}, + {"type":"BASICDTYPE","name":"logic","addr":"(QD)","loc":"d,128:22,128:23","dtypep":"(QD)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(JI)","loc":"d,130:22,130:23","dtypep":"(JI)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(KI)","loc":"d,165:17,165:56","dtypep":"(KI)","keyword":"logic","range":"295:0","generic":true,"rangep": []}, + {"type":"BASICDTYPE","name":"string","addr":"(BG)","loc":"d,165:10,165:16","dtypep":"(BG)","keyword":"string","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(Q)","loc":"e,14:9,14:11","dtypep":"(Q)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(BB)","loc":"e,18:10,18:12","dtypep":"(BB)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(MC)","loc":"e,33:26,33:31","dtypep":"(MC)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, diff --git a/test_regress/t/t_std_identifier.py b/test_regress/t/t_std_identifier.py index 6938ef706..c312a43ce 100755 --- a/test_regress/t/t_std_identifier.py +++ b/test_regress/t/t_std_identifier.py @@ -11,6 +11,6 @@ import vltest_bootstrap test.scenarios('linter') -test.lint(verilator_flags2=["-DTEST_DECLARE_STD"]) +test.lint(verilator_flags2=["-DTEST_DECLARE_STD"], fails=test.vlt_all) # Issue #4705 due to :: test.passes() From d75f41b641f2da2c85924425378b8605e25c1ded Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 13:10:40 -0500 Subject: [PATCH 123/171] Tests: Add param type to t_typename test --- src/V3LinkCells.cpp | 3 ++- test_regress/driver.py | 2 +- test_regress/t/t_typename.out | 1 + test_regress/t/t_typename.v | 7 +++++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index 718541db7..c25ed16f3 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -257,6 +257,7 @@ class LinkCellsVisitor final : public VNVisitor { // For historical reasons virtual interface reference variables remain VARs if (m_varp && !nodep->isVirtual()) m_varp->setIfaceRef(); // Note cannot do modport resolution here; modports are allowed underneath generates + UINFO(4, "Link IfaceRef done: " << nodep << endl); } void visit(AstPackageExport* nodep) override { @@ -502,10 +503,10 @@ class LinkCellsVisitor final : public VNVisitor { AstIfaceRefDType* const idtypep = new AstIfaceRefDType{ nodep->fileline(), nodep->name(), nodep->modp()->name()}; idtypep->ifacep(nullptr); // cellp overrides - // In the case of arrayed interfaces, we replace cellp when de-arraying in V3Inst idtypep->cellp(nodep); // Only set when real parent cell known. AstVar* varp; if (nodep->rangep()) { + // For arrayed interfaces, we replace cellp when de-arraying in V3Inst AstNodeArrayDType* const arrp = new AstUnpackArrayDType{nodep->fileline(), VFlagChildDType{}, idtypep, nodep->rangep()->cloneTree(true)}; diff --git a/test_regress/driver.py b/test_regress/driver.py index 75ded4d44..0e3849280 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -2745,7 +2745,7 @@ if __name__ == '__main__': parser.add_argument('--fail-max', action='store', default=None, - help='run Verilator executable with gdb') + help='after specified number of failures, skip remaining tests') parser.add_argument('--gdb', action='store_true', help='run Verilator executable with gdb') parser.add_argument('--gdbbt', action='store_true', diff --git a/test_regress/t/t_typename.out b/test_regress/t/t_typename.out index b95d23411..133f56582 100644 --- a/test_regress/t/t_typename.out +++ b/test_regress/t/t_typename.out @@ -14,6 +14,7 @@ "bit[2:0]" ==? "bit[2:0]" "int" ==? "int" "bit[9:1]" ==? "bit[9:1]" +"bit[9:1]" ==? "bit[9:1]" "string$[longint]" ==? "string$[longint]" "int$[$]" ==? "int$[$]" "int$[$:3]" ==? "int$[$:3]" diff --git a/test_regress/t/t_typename.v b/test_regress/t/t_typename.v index 624da2576..ea6c2d088 100644 --- a/test_regress/t/t_typename.v +++ b/test_regress/t/t_typename.v @@ -15,7 +15,8 @@ int signed Y; // "int" package A; enum {A,B,C=99} X; // "enum{A=32'sd0,B=32'sd1,C=32'sd99}A::e$1" - typedef bit [9:1'b1] word; // "A::bit[9:1]" + typedef bit [9:1'b1] word_t; // "A::bit[9:1]" + localparam type WORD_T = word_t; endpackage : A import A::*; @@ -31,6 +32,7 @@ module t(/*AUTOARG*/); real r; logic l; typedef bit mybit_t; + localparam type MYBIT_T = mybit_t; mybit_t [2:0] bitp20; mybit_t bitu32 [3:2]; mybit_t bitu31 [3:1][4:5]; @@ -69,7 +71,8 @@ module t(/*AUTOARG*/); `printtype(X, "bit[2:0]"); `printtype(Y, "int"); - `printtype(A::word, "bit[9:1]"); + `printtype(A::word_t, "bit[9:1]"); + `printtype(A::WORD_T, "bit[9:1]"); `printtype(assoc, "string$[longint]"); `printtype(q, "int$[$]"); `printtype(q3, "int$[$:3]"); // Some omit :3 - need it so != unbounded From aa2b653c71a6d9f87810cde47d5d21e1103ae66a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 17:38:02 -0500 Subject: [PATCH 124/171] Internals: With `--dumpi-tree >= 9`, create pre-sort cells.tree --- src/V3Global.cpp | 2 ++ src/V3LinkLevel.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/V3Global.cpp b/src/V3Global.cpp index e65a00081..bd61712cb 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -108,6 +108,8 @@ void V3Global::readFiles() { // Resolve all modules cells refer to V3LinkCells::link(v3Global.rootp(), &filter, &parseSyms); } + + V3Global::dumpCheckGlobalTree("cells", false, dumpTreeEitherLevel() >= 9); } void V3Global::removeStd() { diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 76254c77c..228b9a7de 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -82,7 +82,7 @@ void V3LinkLevel::modSortByLevel() { UASSERT_OBJ(!v3Global.rootp()->modulesp(), v3Global.rootp(), "Unlink didn't work"); for (AstNodeModule* nodep : mods) v3Global.rootp()->addModulesp(nodep); UINFO(9, "modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666 - V3Global::dumpCheckGlobalTree("cells", false, dumpTreeEitherLevel() >= 3); + V3Global::dumpCheckGlobalTree("cellsort", false, dumpTreeEitherLevel() >= 3); } void V3LinkLevel::timescaling(const ModVec& mods) { From abd4c480cd3652d83455e71d82e1b8088d19b27b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 23:00:27 -0500 Subject: [PATCH 125/171] Tests: Fix JSON file number, from earlier commit --- test_regress/t/t_dump_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_regress/t/t_dump_json.py b/test_regress/t/t_dump_json.py index d0cc13c96..71ce0e5d0 100755 --- a/test_regress/t/t_dump_json.py +++ b/test_regress/t/t_dump_json.py @@ -14,7 +14,7 @@ test.top_filename = "t/t_dump.v" test.lint(v_flags=["--dump-tree-json --no-json-edit-nums"]) -test.files_identical(test.obj_dir + "/Vt_dump_json_001_cells.tree.json", test.golden_filename, +test.files_identical(test.obj_dir + "/Vt_dump_json_002_cellsort.tree.json", test.golden_filename, 'logfile') test.passes() From 94fd17e4f73ab3f34308b58ebbb98f04617fc506 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 1 Dec 2024 23:03:19 -0500 Subject: [PATCH 126/171] Internals: Port parsing cleanups --- src/V3LinkParse.cpp | 2 +- src/V3Tristate.cpp | 6 ++++-- src/verilog.y | 49 +++++++++++++++++---------------------------- 3 files changed, 23 insertions(+), 34 deletions(-) diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 5c1ece2ae..238d9dd49 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -292,7 +292,7 @@ class LinkParseVisitor final : public VNVisitor { nodep->v3warn(STATICVAR, "Static variable with assignment declaration declared in a " "loop converted to automatic"); } - if (nodep->varType() != VVarType::PORT) { + if (!nodep->direction().isAny()) { // Not a port if (nodep->lifetime().isNone()) { if (m_lifetimeAllowed) { nodep->lifetime(m_lifetime); diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index c47eea9a5..950de4da3 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -487,8 +487,9 @@ class TristateVisitor final : public TristateBaseVisitor { // Return the master __en for the specified input variable if (!invarp->user1p()) { AstVar* const newp - = new AstVar{invarp->fileline(), isTop ? VVarType::PORT : VVarType::MODULETEMP, + = new AstVar{invarp->fileline(), isTop ? VVarType::VAR : VVarType::MODULETEMP, invarp->name() + "__en", invarp}; + // Inherited VDirection::INPUT UINFO(9, " newenv " << newp << endl); modAddStmtp(invarp, newp); invarp->user1p(newp); // find envar given invarp @@ -540,8 +541,9 @@ class TristateVisitor final : public TristateBaseVisitor { // Return the master __out for the specified input variable if (!m_varAux(invarp).outVarp) { AstVar* const newp - = new AstVar{invarp->fileline(), isTop ? VVarType::PORT : VVarType::MODULETEMP, + = new AstVar{invarp->fileline(), isTop ? VVarType::VAR : VVarType::MODULETEMP, invarp->name() + "__out", invarp}; + // Inherited VDirection::OUTPUT UINFO(9, " newout " << newp << endl); modAddStmtp(invarp, newp); m_varAux(invarp).outVarp = newp; // find outvar given invarp diff --git a/src/verilog.y b/src/verilog.y index 792de8573..c04d47612 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -89,8 +89,8 @@ public: FileLine* m_instModuleFl = nullptr; // Fileline of module referenced for instantiations AstPin* m_instParamp = nullptr; // Parameters for instantiations string m_instModule; // Name of module referenced for instantiations - VVarType m_varDecl; // Type for next signal declaration (reg/wire/etc) - VDirection m_varIO; // Direction for next signal declaration (reg/wire/etc) + VVarType m_varDecl = VVarType::UNKNOWN; // Type for next signal declaration (reg/wire/etc) + VDirection m_varIO = VDirection::NONE; // Direction for next signal declaration (reg/wire/etc) VLifetime m_varLifetime; // Static/Automatic for next signal bool m_impliedDecl = false; // Allow implied wire declarations bool m_varDeclTyped = false; // Var got reg/wire for dedup check @@ -110,10 +110,7 @@ public: static int s_modTypeImpNum; // Implicit type number, incremented each module // CONSTRUCTORS - V3ParseGrammar() { - m_varDecl = VVarType::UNKNOWN; - m_varIO = VDirection::NONE; - } + V3ParseGrammar() {} static V3ParseGrammar* singletonp() { static V3ParseGrammar singleton; return &singleton; @@ -203,7 +200,6 @@ public: << name << "'"); } } - void setVarDecl(VVarType type) { m_varDecl = type; } void setDType(AstNodeDType* dtypep) { if (m_varDTypep) VL_DO_CLEAR(m_varDTypep->deleteTree(), m_varDTypep = nullptr); m_varDTypep = dtypep; @@ -312,28 +308,19 @@ int V3ParseGrammar::s_modTypeImpNum = 0; #define CRELINE() (PARSEP->bisonLastFileline()->copyOrSameFileLineApplied()) #define FILELINE_OR_CRE(nodep) ((nodep) ? (nodep)->fileline() : CRELINE()) -#define VARRESET_LIST(decl) \ +#define VARRESET_LIST(decl) VARRESET__PVT(decl, 1) // Start of pinlist +#define VARRESET_NONLIST(decl) VARRESET__PVT(decl, 0); // Not in a pinlist +#define VARRESET__PVT(decl, pinNumStart) \ { \ - GRAMMARP->m_pinNum = 1; \ - VARRESET(); \ VARDECL(decl); \ - } // Start of pinlist -#define VARRESET_NONLIST(decl) \ - { \ - GRAMMARP->m_pinNum = 0; \ - VARRESET(); \ - VARDECL(decl); \ - } // Not in a pinlist -#define VARRESET() \ - { \ - VARDECL(UNKNOWN); \ VARIO(NONE); \ VARDTYPE_NDECL(nullptr); \ + GRAMMARP->m_pinNum = (pinNumStart); \ GRAMMARP->m_varLifetime = VLifetime::NONE; \ GRAMMARP->m_varDeclTyped = false; \ } #define VARDECL(type) \ - { GRAMMARP->setVarDecl(VVarType::type); } + { GRAMMARP->m_varDecl = VVarType::type; } #define VARIO(type) \ { GRAMMARP->m_varIO = VDirection::type; } #define VARLIFE(flag) \ @@ -1478,10 +1465,10 @@ portsStarE: // IEEE: .* + list_of_ports + list_of_port_decla | '(' ')' { $$ = nullptr; } // // .* expanded from module_declaration //UNSUP '(' yP_DOTSTAR ')' { UNSUP } - | '(' { VARRESET_LIST(PORT); - GRAMMARP->m_pinAnsi = true; } - /*cont*/ list_of_ports ')' { $$ = $3; VARRESET_NONLIST(UNKNOWN); - GRAMMARP->m_pinAnsi = false; } + | '(' + /*mid*/ { VARRESET_LIST(PORT); GRAMMARP->m_pinAnsi = true; } + /*cont*/ list_of_ports ')' + { $$ = $3; VARRESET_NONLIST(UNKNOWN); GRAMMARP->m_pinAnsi = false; } ; list_of_portsE: // IEEE: list_of_ports + list_of_port_declarations @@ -1499,7 +1486,7 @@ portAndTagE: { int p = PINNUMINC(); const string name = "__pinNumber" + cvtToStr(p); $$ = new AstPort{CRELINE(), p, name}; - AstVar* varp = new AstVar{CRELINE(), VVarType::PORT, name, VFlagChildDType{}, + AstVar* varp = new AstVar{CRELINE(), VVarType::WIRE, name, VFlagChildDType{}, new AstBasicDType{CRELINE(), LOGIC_IMPLICIT}}; varp->declDirection(VDirection::INPUT); varp->direction(VDirection::INPUT); @@ -3796,7 +3783,7 @@ statementFor: // IEEE: part of statement $$->addStmtsp(new AstWhile{$1, new AstConst{$1, AstConst::BitTrue{}}, $7, $5}); } ; beginForParen: // IEEE: Part of statement (for loop beginning paren) - '(' { VARRESET(); } + '(' { VARRESET_NONLIST(UNKNOWN); } ; statementVerilatorPragmas: @@ -5449,7 +5436,7 @@ let_declaration: // IEEE: let_declaration let_port_listE: // IEEE: [ let_port_list ] /*empty*/ { $$ = nullptr; } | /*emptyStart*/ - /*mid*/ { VARRESET_LIST(UNKNOWN); VARIO(INOUT); } + /*mid*/ { VARRESET_LIST(VAR); VARIO(INOUT); } /*cont*/ let_port_list { $$ = $2; VARRESET_NONLIST(UNKNOWN); } ; @@ -5461,7 +5448,7 @@ let_port_list: // IEEE: let_port_list let_port_item: // IEEE: let_port_Item // // IEEE: Expanded let_formal_type yUNTYPED idAny/*formal_port_identifier*/ variable_dimensionListE exprEqE - { $$ = new AstVar{$2, VVarType::PORT, *$2, VFlagChildDType{}, + { $$ = new AstVar{$2, VVarType::VAR, *$2, VFlagChildDType{}, new AstBasicDType{$2, LOGIC_IMPLICIT}}; $$->direction(VDirection::INOUT); $$->lifetime(VLifetime::AUTOMATIC); @@ -5469,7 +5456,7 @@ let_port_item: // IEEE: let_port_Item PINNUMINC(); } | data_type idAny/*formal_port_identifier*/ variable_dimensionListE exprEqE { BBUNSUP($1, "Unsupported: let typed ports"); - $$ = new AstVar{$2, VVarType::PORT, *$2, VFlagChildDType{}, + $$ = new AstVar{$2, VVarType::VAR, *$2, VFlagChildDType{}, new AstBasicDType{$2, LOGIC_IMPLICIT}}; $$->direction(VDirection::INOUT); $$->lifetime(VLifetime::AUTOMATIC); @@ -5477,7 +5464,7 @@ let_port_item: // IEEE: let_port_Item PINNUMINC(); } | implicit_typeE id/*formal_port_identifier*/ variable_dimensionListE exprEqE { if ($1) BBUNSUP($1, "Unsupported: let typed ports"); - $$ = new AstVar{$2, VVarType::PORT, *$2, VFlagChildDType{}, + $$ = new AstVar{$2, VVarType::VAR, *$2, VFlagChildDType{}, new AstBasicDType{$2, LOGIC_IMPLICIT}}; $$->direction(VDirection::INOUT); $$->lifetime(VLifetime::AUTOMATIC); From a668b7c6586b436d7af367ff589cd78857bb8037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Mon, 2 Dec 2024 11:43:26 +0100 Subject: [PATCH 127/171] Fix missing VlProcess handle in coroutines with splits (#5623) (#5650) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Bartłomiej Chmiel --- src/V3Sched.cpp | 1 + src/V3SchedTiming.cpp | 10 +-- test_regress/t/t_disable_fork2.v | 11 ++- test_regress/t/t_disable_fork2_split.py | 18 ++++ test_regress/t/t_vlprocess_missing.py | 106 ++++++++++++++++++++++++ 5 files changed, 139 insertions(+), 7 deletions(-) create mode 100755 test_regress/t/t_disable_fork2_split.py create mode 100755 test_regress/t/t_vlprocess_missing.py diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index 46fb79354..d85cf93b8 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -291,6 +291,7 @@ AstCFunc* splitCheckCreateNewSubFunc(AstCFunc* ofuncp) { subFuncp->isLoose(true); subFuncp->slow(ofuncp->slow()); subFuncp->declPrivate(ofuncp->declPrivate()); + if (ofuncp->needProcess()) subFuncp->setNeedProcess(); return subFuncp; }; diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp index 13e2f0b88..7e46ca8ec 100644 --- a/src/V3SchedTiming.cpp +++ b/src/V3SchedTiming.cpp @@ -368,7 +368,9 @@ void transformForks(AstNetlist* const netlistp) { // Start with children, so later we only find awaits that are actually in this begin m_beginHasAwaits = false; iterateChildrenConst(nodep); - if (m_beginHasAwaits || nodep->needProcess()) { + if (!nodep->stmtsp()) { + nodep->unlinkFrBack(); + } else if (m_beginHasAwaits || nodep->needProcess()) { UASSERT_OBJ(!nodep->name().empty(), nodep, "Begin needs a name"); // Create a function to put this begin's statements in FileLine* const flp = nodep->fileline(); @@ -407,11 +409,7 @@ void transformForks(AstNetlist* const netlistp) { } else { // The begin has neither awaits nor a process::self call, just inline the // statements - if (nodep->stmtsp()) { - nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext()); - } else { - nodep->unlinkFrBack(); - } + nodep->replaceWith(nodep->stmtsp()->unlinkFrBackWithNext()); } VL_DO_DANGLING(nodep->deleteTree(), nodep); } diff --git a/test_regress/t/t_disable_fork2.v b/test_regress/t/t_disable_fork2.v index 118e3e7f5..6e52acac8 100644 --- a/test_regress/t/t_disable_fork2.v +++ b/test_regress/t/t_disable_fork2.v @@ -15,7 +15,8 @@ // - a function taking VlProcess argument shared between a process that // allocates VlProcess, and one that doesnt, // - a function that has a delay and obtains VlProcess argument, -// - a function that has a delay and doesn't obtain it. +// - a function that has a delay and doesn't obtain it, +// - an empty fork with disable fork. // // Blocks below contain info on whether they should (YES) or shouldn't (NO) // be emitted as functions with a VlProcess argument. @@ -38,6 +39,13 @@ class Cls; task delay_func; /*NO*/ fork /*NO*/ #1 $write("Finished *-*\n"); join_none endtask + task empty_fork; + fork + begin + end + join_none + disable fork; + endtask endclass module t; @@ -47,6 +55,7 @@ module t; fork /*YES*/ cls.common_func(); join_none cls.fork_func(); cls.disable_fork_func(); + cls.empty_fork(); cls.print(); end diff --git a/test_regress/t/t_disable_fork2_split.py b/test_regress/t/t_disable_fork2_split.py new file mode 100755 index 000000000..3e66b3894 --- /dev/null +++ b/test_regress/t/t_disable_fork2_split.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = "t_disable_fork2.v" + +# Validate if splitted functions get vlProcess handle +test.compile(verilator_flags2=["--timing --output-split-cfuncs 1"]) + +test.passes() diff --git a/test_regress/t/t_vlprocess_missing.py b/test_regress/t/t_vlprocess_missing.py new file mode 100755 index 000000000..35076ad18 --- /dev/null +++ b/test_regress/t/t_vlprocess_missing.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') +test.top_filename = test.obj_dir + "/t_vlprocess_missing.v" + +# Number of tests to generate +NUM_TESTS = 200 + +# Testbench header template +HEADER = """\ +module Testbench; + + logic clk; + logic reset; + + // Clock driver + initial begin + clk = 0; + forever begin + #5 clk = ~clk; + end + end + + task automatic advance_clock(int n = 1); + repeat (n) @(posedge clk); + endtask + +""" + +# Test task template +TEST_TASK_TEMPLATE = """ + task automatic test_{num}(); + int counter = 0; + int expected_value = {num}; + + // Timeout wait + fork + begin + advance_clock(10000); + $error("Timeout"); + end + join_none + wait (counter == expected_value); + disable fork; + + while (counter < expected_value) begin + advance_clock(); + counter++; + end + endtask +""" + +# Testbench footer template +FOOTER = " initial begin" + +# Call template for invoking each test task +CALL_TEMPLATE = " test_{num}();\n" + +# Footer end +FOOTER_END = """ + $finish; + end + +endmodule +""" + + +def gen(filename, num_tests): + """ + Generates a SystemVerilog testbench with the specified number of tests. + + Args: + filename (str): The output file name for the generated testbench. + num_tests (int): The number of test tasks to generate. + """ + with open(filename, 'w', encoding="utf-8") as fh: + fh.write("// Generated by t_vlprocess_missing.py\n") + + # Write the header + fh.write(HEADER) + + # Generate the test tasks + for i in range(1, num_tests + 1): + fh.write(TEST_TASK_TEMPLATE.format(num=i)) + + # Write the initial block with test calls + fh.write(FOOTER) + for i in range(1, num_tests + 1): + fh.write(CALL_TEMPLATE.format(num=i)) + fh.write(FOOTER_END) + + +gen(test.top_filename, NUM_TESTS) + +test.compile(verilator_flags2=["--binary"]) + +test.passes() From b4e91c87a6dd8d2e502fe78f757b1d4e97f748c8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 2 Dec 2024 07:20:40 -0500 Subject: [PATCH 128/171] Tests: Add t_interface_find --- test_regress/t/t_interface_find.py | 18 +++++++++++ test_regress/t/t_interface_find.v | 43 +++++++++++++++++++++++++++ test_regress/t/t_interface_find_ifc.v | 9 ++++++ 3 files changed, 70 insertions(+) create mode 100755 test_regress/t/t_interface_find.py create mode 100644 test_regress/t/t_interface_find.v create mode 100644 test_regress/t/t_interface_find_ifc.v diff --git a/test_regress/t/t_interface_find.py b/test_regress/t/t_interface_find.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_find.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_find.v b/test_regress/t/t_interface_find.v new file mode 100644 index 000000000..6566a7381 --- /dev/null +++ b/test_regress/t/t_interface_find.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +// Auto-resolved by t_interface_find_ifc.v +// interface t_interface_find_ifc; + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + integer cyc=1; + + t_interface_find_ifc itop(); + + sub c1 (.isub(itop), + .i_value(4'h4)); + + always @ (posedge clk) begin + cyc <= cyc + 1; + if (cyc==20) begin + if (c1.i_value != 4) $stop; // 'Normal' crossref just for comparison + if (itop.value != 4) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +module sub + ( + t_interface_find_ifc isub, + input logic [3:0] i_value + ); + + always @* begin + isub.value = i_value; + end +endmodule : sub diff --git a/test_regress/t/t_interface_find_ifc.v b/test_regress/t/t_interface_find_ifc.v new file mode 100644 index 000000000..2866d850b --- /dev/null +++ b/test_regress/t/t_interface_find_ifc.v @@ -0,0 +1,9 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface t_interface_find_ifc; + logic [3:0] value; +endinterface From b16b48f45812cd51aea89ad508899cbffda0d7d0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 2 Dec 2024 07:21:24 -0500 Subject: [PATCH 129/171] Internals: Misc ANSI port parsing cleanups; baseline for future commit. --- src/V3Ast.h | 2 +- src/V3AstNodeOther.h | 5 ++++- src/V3ParseGrammar.cpp | 5 +++-- src/verilog.y | 27 ++++++++++++++++----------- 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/V3Ast.h b/src/V3Ast.h index cbee6890a..961dd146c 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -904,7 +904,7 @@ public: TRIWIRE, TRI0, TRI1, - PORT, // Used in parser and V3Fork to recognize ports + PORT, // Used in parser to recognize ports BLOCKTEMP, MODULETEMP, STMTTEMP, diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 155237d80..ec8c777e3 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2082,7 +2082,10 @@ public: bool isPrimaryIO() const VL_MT_SAFE { return m_primaryIO; } bool isPrimaryInish() const { return isPrimaryIO() && isNonOutput(); } bool isIfaceRef() const { return varType() == VVarType::IFACEREF; } - void setIfaceRef() { m_varType = VVarType::IFACEREF; } + void setIfaceRef() { + m_direction = VDirection::NONE; + m_varType = VVarType::IFACEREF; + } bool isIfaceParent() const { return m_isIfaceParent; } bool isInternal() const { return m_isInternal; } bool isSignal() const { return varType().isSignal(); } diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 6451ba514..481965f22 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -193,7 +193,8 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name, AstNodeDType* dtypep = GRAMMARP->m_varDTypep; UINFO(5, " creVar " << name << " decl=" << GRAMMARP->m_varDecl << " io=" << GRAMMARP->m_varIO << " dt=" << (dtypep ? "set" : "") << endl); - if (GRAMMARP->m_varIO == VDirection::NONE && GRAMMARP->m_varDecl == VVarType::PORT) { + if (GRAMMARP->m_varIO == VDirection::NONE // In non-ANSI port list + && GRAMMARP->m_varDecl == VVarType::PORT) { // Just a port list with variable name (not v2k format); AstPort already created if (dtypep) fileline->v3warn(E_UNSUPPORTED, "Unsupported: Ranges ignored in port-lists"); if (arrayp) VL_DO_DANGLING(arrayp->deleteTree(), arrayp); @@ -222,7 +223,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name, // UINFO(0,"CREVAR "<ascii()<<" decl="<m_varDecl.ascii()<<" // io="<m_varIO.ascii()<m_varDecl; - if (type == VVarType::UNKNOWN) { + if (type == VVarType::UNKNOWN) { // e.g. "output" non-ANSI standalone direction (vs "reg") if (GRAMMARP->m_varIO.isAny()) { type = VVarType::PORT; } else { diff --git a/src/verilog.y b/src/verilog.y index c04d47612..9afdbfbdc 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -323,6 +323,11 @@ int V3ParseGrammar::s_modTypeImpNum = 0; { GRAMMARP->m_varDecl = VVarType::type; } #define VARIO(type) \ { GRAMMARP->m_varIO = VDirection::type; } +// Set direction to default-input when detect inside an ANSI port list +#define VARIOANSI(type) \ + { \ + if (GRAMMARP->m_varIO == VDirection::NONE) VARIO(INPUT); \ + } #define VARLIFE(flag) \ { GRAMMARP->m_varLifetime = flag; } #define VARDTYPE(dtypep) \ @@ -1471,7 +1476,7 @@ portsStarE: // IEEE: .* + list_of_ports + list_of_port_decla { $$ = $3; VARRESET_NONLIST(UNKNOWN); GRAMMARP->m_pinAnsi = false; } ; -list_of_portsE: // IEEE: list_of_ports + list_of_port_declarations +list_of_portsE: // IEEE: [ list_of_ports + list_of_port_declarations ] portAndTagE { $$ = $1; } | list_of_portsE ',' portAndTagE { $$ = addNextNull($1, $3); } ; @@ -1519,13 +1524,13 @@ port: // ==IEEE: port { // VAR for now, but V3LinkCells may call setIfcaeRef on it later $$ = $3; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, "", *$2}; - VARDTYPE(dtp); + VARDTYPE(dtp); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE { // VAR for now, but V3LinkCells may call setIfcaeRef on it later $$ = $5; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, $4, "", *$2, *$4}; - VARDTYPE(dtp); + VARDTYPE(dtp); VARIOANSI(); addNextNull($$, VARDONEP($$, $6, $7)); } | portDirNetE yINTERFACE portSig rangeListE sigAttrListE { $$ = nullptr; BBUNSUP($2, "Unsupported: generic interfaces"); } @@ -1537,7 +1542,7 @@ port: // ==IEEE: port BBUNSUP($2, "Unsupported: interconnect"); AstNodeDType* const dtp = GRAMMARP->addRange( new AstBasicDType{$2, LOGIC_IMPLICIT, $3}, $4, true); - VARDTYPE(dtp); + VARDTYPE(dtp); VARIOANSI(); addNextNull($$, VARDONEP($$, $6, $7)); } // // // IEEE: ansi_port_declaration, with [port_direction] removed @@ -1576,15 +1581,15 @@ port: // ==IEEE: port // // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr. // | portDirNetE data_type portSig variable_dimensionListE sigAttrListE - { $$ = $3; VARDTYPE($2); addNextNull($$, VARDONEP($$, $4, $5)); } + { $$ = $3; VARDTYPE($2); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE - { $$ = $4; VARDTYPE($3); addNextNull($$, VARDONEP($$, $5, $6)); } + { $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE - { $$ = $4; VARDTYPE($3); addNextNull($$, VARDONEP($$, $5, $6)); } + { $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } | portDirNetE signing portSig variable_dimensionListE sigAttrListE { $$ = $3; AstNodeDType* const dtp = new AstBasicDType{$3->fileline(), LOGIC_IMPLICIT, $2}; - VARDTYPE_NDECL(dtp); + VARDTYPE_NDECL(dtp); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE signingE rangeList portSig variable_dimensionListE sigAttrListE { $$ = $4; @@ -1596,13 +1601,13 @@ port: // ==IEEE: port { $$ = $2; /*VARDTYPE-same*/ addNextNull($$, VARDONEP($$, $3, $4)); } // | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr - { $$ = $3; VARDTYPE($2); + { $$ = $3; VARDTYPE($2); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr - { $$ = $4; VARDTYPE($3); + { $$ = $4; VARDTYPE($3); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr - { $$ = $4; VARDTYPE($3); + { $$ = $4; VARDTYPE($3); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } | portDirNetE /*implicit*/ portSig variable_dimensionListE sigAttrListE '=' constExpr { $$ = $2; /*VARDTYPE-same*/ From 4781a6046aa7417132ade1e4da34e07a5b22d114 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 2 Dec 2024 07:35:44 -0500 Subject: [PATCH 130/171] Update error as misnamed port dtype might be interface --- src/V3LinkDot.cpp | 2 +- src/verilog.y | 2 +- test_regress/t/t_typedef_no_bad.out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index bde24b439..0cbc5bc79 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -4137,7 +4137,7 @@ class LinkDotResolveVisitor final : public VNVisitor { if (foundp) { nodep->v3error("Expecting a data type: " << nodep->prettyNameQ()); } else { - nodep->v3error("Can't find typedef: " << nodep->prettyNameQ()); + nodep->v3error("Can't find typedef/interface: " << nodep->prettyNameQ()); } } } diff --git a/src/verilog.y b/src/verilog.y index 9afdbfbdc..0b761d24d 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1520,7 +1520,7 @@ port: // ==IEEE: port // // IEEE: interface_port_header port_identifier { unpacked_dimension } // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation - portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE + portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE { // VAR for now, but V3LinkCells may call setIfcaeRef on it later $$ = $3; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, "", *$2}; diff --git a/test_regress/t/t_typedef_no_bad.out b/test_regress/t/t_typedef_no_bad.out index 1d17e5fc6..e1e4ceaf8 100644 --- a/test_regress/t/t_typedef_no_bad.out +++ b/test_regress/t/t_typedef_no_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_typedef_no_bad.v:10:4: Can't find typedef: 'sometype' +%Error: t/t_typedef_no_bad.v:10:4: Can't find typedef/interface: 'sometype' 10 | sometype p; | ^~~~~~~~ %Error: Exiting due to From b6f292f556e1e703eb68e289835c43d926b17c82 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Mon, 2 Dec 2024 15:08:47 -0500 Subject: [PATCH 131/171] Fix imported array assignment literals (#5642) (#5648) --- src/V3LinkDot.cpp | 5 ++++- test_regress/t/t_param_pattern_init.v | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 0cbc5bc79..9a5933af2 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2779,7 +2779,10 @@ class LinkDotResolveVisitor final : public VNVisitor { if (AstVar* const varp = VN_CAST(foundp->nodep(), Var)) { if (varp->isParam() || varp->isGenVar()) { // Attach found Text reference to PatMember - nodep->varrefp(new AstVarRef{nodep->fileline(), varp, VAccess::READ}); + nodep->varrefp( + new AstVarRef{nodep->fileline(), + foundp->imported() ? foundp->classOrPackagep() : nullptr, + varp, VAccess::READ}); UINFO(9, indent() << " new " << nodep->varrefp() << endl); } } diff --git a/test_regress/t/t_param_pattern_init.v b/test_regress/t/t_param_pattern_init.v index f175e4bcf..69fefffec 100644 --- a/test_regress/t/t_param_pattern_init.v +++ b/test_regress/t/t_param_pattern_init.v @@ -7,6 +7,15 @@ `define stop $stop `define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); +package some_pkg; + localparam FOO = 5; + localparam BAR = 6; + + typedef enum int { + QUX = 7 + } pkg_enum_t; +endpackage + module t (/*AUTOARG*/ // Inputs clk @@ -69,6 +78,22 @@ module t (/*AUTOARG*/ `checkh(enum_array[2], 32'ha5a5); end + logic [31:0] package_array [8]; + + import some_pkg::*; + always_comb package_array = '{ + FOO: 32'h9876, + BAR: 32'h1212, + QUX: 32'h5432, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(package_array[5], 32'h9876); + `checkh(package_array[6], 32'h1212); + `checkh(package_array[7], 32'h5432); + end + always_ff @(posedge clk) begin cyc <= cyc + 1; if (cyc == 2) begin From e9a1c75b7f2fb6d4c0572ee19a3fdbeeca75660c Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Mon, 2 Dec 2024 18:33:34 -0500 Subject: [PATCH 132/171] Tests: Demonstrate unsupported scoped pattern array init (#5652) --- .../t/t_scoped_param_pattern_init_unsup.out | 4 ++ .../t/t_scoped_param_pattern_init_unsup.py | 16 ++++++ .../t/t_scoped_param_pattern_init_unsup.v | 50 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 test_regress/t/t_scoped_param_pattern_init_unsup.out create mode 100755 test_regress/t/t_scoped_param_pattern_init_unsup.py create mode 100644 test_regress/t/t_scoped_param_pattern_init_unsup.v diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.out b/test_regress/t/t_scoped_param_pattern_init_unsup.out new file mode 100644 index 000000000..377634d74 --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.out @@ -0,0 +1,4 @@ +%Error: t/t_scoped_param_pattern_init_unsup.v:30:22: syntax error, unexpected ':', expecting ',' or '}' + 30 | some_pkg::FOO: 32'h9876, + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.py b/test_regress/t/t_scoped_param_pattern_init_unsup.py new file mode 100755 index 000000000..efe8cc01c --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_scoped_param_pattern_init_unsup.v b/test_regress/t/t_scoped_param_pattern_init_unsup.v new file mode 100644 index 000000000..ebaa9cd89 --- /dev/null +++ b/test_regress/t/t_scoped_param_pattern_init_unsup.v @@ -0,0 +1,50 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2010 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); + +package some_pkg; + localparam FOO = 5; + localparam BAR = 6; + + typedef enum int { + QUX = 7 + } pkg_enum_t; +endpackage + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + int cyc = 0; + + logic [31:0] package_array [8]; + + always_comb package_array = '{ + some_pkg::FOO: 32'h9876, + some_pkg::BAR: 32'h1212, + some_pkg::QUX: 32'h5432, + default: 0 + }; + + always_ff @(posedge clk) begin + `checkh(package_array[5], 32'h9876); + `checkh(package_array[6], 32'h1212); + `checkh(package_array[7], 32'h5432); + end + + always_ff @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 2) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule From a64660a530538aeb8707fb0276fe16c2468869a2 Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Tue, 3 Dec 2024 13:57:50 +0100 Subject: [PATCH 133/171] Fix foreach mixed array (#5655) (#5656) --- src/V3Begin.cpp | 11 ++- test_regress/t/t_foreach_array.v | 115 ++++++++++++++++++++----------- 2 files changed, 82 insertions(+), 44 deletions(-) diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index f20ba4f6d..7d23f8489 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -424,6 +424,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { AstNode* bodyPointp = new AstBegin{nodep->fileline(), "[EditWrapper]", nullptr}; AstNode* newp = nullptr; AstNode* lastp = nodep; + AstVar* nestedIndexp = nullptr; // subfromp used to traverse each dimension of multi-d variable-sized unpacked array (queue, // dyn-arr and associative-arr) AstNodeExpr* subfromp = fromp->cloneTreePure(false); @@ -456,8 +457,13 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { } } else if (VN_IS(fromDtp, DynArrayDType) || VN_IS(fromDtp, QueueDType)) { AstConst* const leftp = new AstConst{fl, 0}; - AstNodeExpr* const rightp - = new AstCMethodHard{fl, subfromp->cloneTreePure(false), "size"}; + AstNodeExpr* const rightp = new AstCMethodHard{ + fl, + VN_IS(subfromp->dtypep(), NodeArrayDType) + ? new AstArraySel{fl, subfromp->cloneTreePure(false), + new AstVarRef{fl, nestedIndexp, VAccess::READ}} + : subfromp->cloneTreePure(false), + "size"}; AstVarRef* varRefp = new AstVarRef{fl, varp, VAccess::READ}; subfromp = new AstCMethodHard{fl, subfromp, "at", varRefp}; subfromp->dtypep(fromDtp); @@ -508,6 +514,7 @@ AstNode* V3Begin::convertToWhile(AstForeach* nodep) { if (!newp) newp = loopp; } // Prep for next + nestedIndexp = varp; fromDtp = fromDtp->subDTypep(); } // The parser validates we don't have "foreach (array[,,,])" diff --git a/test_regress/t/t_foreach_array.v b/test_regress/t/t_foreach_array.v index 7b4a8eca6..2f4297c14 100755 --- a/test_regress/t/t_foreach_array.v +++ b/test_regress/t/t_foreach_array.v @@ -5,19 +5,30 @@ // SPDX-License-Identifier: CC0-1.0 module t_foreach_array; - + // Define various structures to test foreach behavior int dyn_arr[][]; int queue[$][$]; int unpacked_arr [3:1][9:8]; int associative_array_3d[string][string][string]; - int count_que; - int exp_count_que; - int count_dyn; - int exp_count_dyn; - int count_unp; - int exp_count_unp; + int queue_unp[$][3]; // Outer dynamic queue with fixed-size inner arrays + int unp_queue[3][$]; // Fixed-size outer array with dynamic inner queues + int dyn_queue[][]; // Fully dynamic 2D array + int queue_dyn[$][]; // Outer dynamic queue with dynamic inner queues + int dyn_unp[][3]; // Dynamic outer array with fixed-size inner arrays + int unp_dyn[3][]; // Fixed-size outer array with dynamic inner arrays + + // Define counter for various structures of array + int count_que, exp_count_que; + int count_dyn, exp_count_dyn; + int count_unp, exp_count_unp; int count_assoc; + int count_queue_unp, exp_count_queue_unp; + int count_unp_queue, exp_count_unp_queue; + int count_dyn_queue, exp_count_dyn_queue; + int count_queue_dyn, exp_count_queue_dyn; + int count_dyn_unp, exp_count_dyn_unp; + int count_unp_dyn, exp_count_unp_dyn; string k1, k2, k3; @@ -35,57 +46,77 @@ module t_foreach_array; associative_array_3d["key2"]["subkey1"]["subsubkey2"] = 8; associative_array_3d["key2"]["subkey3"]["subsubkey1"] = 9; + queue_unp = '{'{1, 2, 3}, '{4, 5, 6}, '{7, 8, 9}}; + unp_queue[0] = '{10, 11}; + unp_queue[1] = '{12, 13, 14}; + unp_queue[2] = '{15}; + dyn_queue = '{'{16, 17}, '{18, 19, 20}}; + queue_dyn = '{'{21, 22}, '{23, 24, 25}}; + dyn_unp = '{'{26, 27, 28}, '{29, 30, 31}}; + unp_dyn[0] = '{32, 33}; + unp_dyn[1] = '{34, 35, 36}; + unp_dyn[2] = '{37}; + + // Perform foreach loop counting and expected value calculation count_que = 0; - - foreach(queue[i, j]) begin - count_que++; - end - + foreach(queue[i, j]) count_que++; exp_count_que = 0; - foreach(queue[i]) begin - foreach(queue[i][j]) begin - exp_count_que++; - end - end + foreach(queue[i]) foreach(queue[i][j]) exp_count_que++; count_dyn = 0; - - foreach(dyn_arr[i, j]) begin - count_dyn++; - end - + foreach(dyn_arr[i, j]) count_dyn++; exp_count_dyn = 0; - - foreach(dyn_arr[i]) begin - foreach(dyn_arr[i][j]) begin - exp_count_dyn++; - end - end + foreach(dyn_arr[i]) foreach(dyn_arr[i][j]) exp_count_dyn++; count_unp = 0; - - foreach(unpacked_arr[i, j]) begin - count_unp++; - end - + foreach(unpacked_arr[i, j]) count_unp++; exp_count_unp = 0; - - foreach(unpacked_arr[i]) begin - foreach(unpacked_arr[i][j]) begin - exp_count_unp++; - end - end + foreach(unpacked_arr[i]) foreach(unpacked_arr[i][j]) exp_count_unp++; count_assoc = 0; + foreach(associative_array_3d[k1, k2, k3]) count_assoc++; - foreach(associative_array_3d[k1, k2, k3]) begin - count_assoc++; - end + count_queue_unp = 0; + foreach (queue_unp[i, j]) count_queue_unp++; + exp_count_queue_unp = 0; + foreach (queue_unp[i]) foreach (queue_unp[i][j]) exp_count_queue_unp++; + count_unp_queue = 0; + foreach (unp_queue[i, j]) count_unp_queue++; + exp_count_unp_queue = 0; + foreach (unp_queue[i]) foreach (unp_queue[i][j]) exp_count_unp_queue++; + + count_dyn_queue = 0; + foreach (dyn_queue[i, j]) count_dyn_queue++; + exp_count_dyn_queue = 0; + foreach (dyn_queue[i]) foreach (dyn_queue[i][j]) exp_count_dyn_queue++; + + count_queue_dyn = 0; + foreach (queue_dyn[i, j]) count_queue_dyn++; + exp_count_queue_dyn = 0; + foreach (queue_dyn[i]) foreach (queue_dyn[i][j]) exp_count_queue_dyn++; + + count_dyn_unp = 0; + foreach (dyn_unp[i, j]) count_dyn_unp++; + exp_count_dyn_unp = 0; + foreach (dyn_unp[i]) foreach (dyn_unp[i][j]) exp_count_dyn_unp++; + + count_unp_dyn = 0; + foreach (unp_dyn[i, j]) count_unp_dyn++; + exp_count_unp_dyn = 0; + foreach (unp_dyn[i]) foreach (unp_dyn[i][j]) exp_count_unp_dyn++; + + // Verification checks if (count_que != 6 || count_que != exp_count_que) $stop; if (count_dyn != 12 || count_dyn != exp_count_dyn) $stop; if (count_unp != 6 || count_unp != exp_count_unp) $stop; if (count_assoc != 9) $stop; + if (count_queue_unp != exp_count_queue_unp) $stop; + if (count_unp_queue != exp_count_unp_queue) $stop; + if (count_dyn_queue != exp_count_dyn_queue) $stop; + if (count_queue_dyn != exp_count_queue_dyn) $stop; + if (count_dyn_unp != exp_count_dyn_unp) $stop; + if (count_unp_dyn != exp_count_unp_dyn) $stop; $write("*-* All Finished *-*\\n"); $finish; From 59fd238a05eaf7ed0b9c828f912b1272191bd077 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 2 Dec 2024 18:31:46 -0500 Subject: [PATCH 134/171] Tests: Add t_interface_hidden --- test_regress/t/t_interface_hidden.py | 18 +++++ test_regress/t/t_interface_hidden.v | 76 ++++++++++++++++++ test_regress/t/t_unpacked_concat.v | 110 +++++++++++++-------------- test_regress/t/t_unpacked_init.v | 9 +++ 4 files changed, 158 insertions(+), 55 deletions(-) create mode 100755 test_regress/t/t_interface_hidden.py create mode 100644 test_regress/t/t_interface_hidden.v diff --git a/test_regress/t/t_interface_hidden.py b/test_regress/t/t_interface_hidden.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_hidden.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_hidden.v b/test_regress/t/t_interface_hidden.v new file mode 100644 index 000000000..04b460d92 --- /dev/null +++ b/test_regress/t/t_interface_hidden.v @@ -0,0 +1,76 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2013 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + integer cyc=1; + + ifc ifc(); // Cell name hides interface's name + assign ifc.ifi = 55; + + sub sub (.isub(ifc)); // Cell name hides module's name + + int om; + + mod_or_type mot (.*); + + hides_with_type hides_type(); + hides_with_decl hides_decl(); + + always @ (posedge clk) begin + cyc <= cyc + 1; + if (cyc == 20) begin + if (om != 22) $stop; + if (mot.LOCAL != 22) $stop; + if (ifc.ifo != 55) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule + +module sub + ( + ifc isub + ); + always @* begin + isub.ifo = isub.ifi; + end +endmodule + +module mod_or_type(output int om); + localparam LOCAL = 22; + initial om = 22; +endmodule + +module hides_with_type(); + typedef int ifc; // Hides interface + typedef int mod_or_type; // Hides module + + ifc /*=int*/ hides_ifc; + mod_or_type /*=int*/ hides_mod; + + initial hides_ifc = 33; + initial hides_mod = 44; +endmodule + +module hides_with_decl(); + int ifc; // Hides interface + int mod_or_type; // Hides module + + initial ifc = 66; + initial mod_or_type = 77; +endmodule + +interface ifc; + localparam LOCAL = 12; + int ifi; + int ifo; +endinterface diff --git a/test_regress/t/t_unpacked_concat.v b/test_regress/t/t_unpacked_concat.v index 468518ab2..f1ca793b5 100644 --- a/test_regress/t/t_unpacked_concat.v +++ b/test_regress/t/t_unpacked_concat.v @@ -6,90 +6,90 @@ module t (/*AUTOARG*/); - typedef int AI3[1:3]; - AI3 A3; - int A9[1:9]; + typedef int ai3_t[1:3]; + ai3_t a3; + int a9[1:9]; logic [2:0] s0; logic [2:0] s1[1:3]; - logic [2:0] s2[3:1]; + logic [2:0] s1b[3:1]; logic [2:0] s3[2:8]; - logic [2:0] s4[8:2]; + logic [2:0] s3b[8:2]; initial begin s0 = 3'd1; s1[1] = 3'd2; s1[2] = 3'd3; s1[3] = 3'd4; - s2[1] = 3'd5; - s2[2] = 3'd6; - s2[3] = 3'd7; + s1b[1] = 3'd5; + s1b[2] = 3'd6; + s1b[3] = 3'd7; - A3 = '{1, 2, 3}; - A9 = {A3, 4, 5, A3, 6}; - if (A9[1] != 1) $stop; - if (A9[2] != 2) $stop; - if (A9[3] != 3) $stop; - if (A9[4] != 4) $stop; - if (A9[5] != 5) $stop; - if (A9[6] != 1) $stop; - if (A9[7] != 2) $stop; - if (A9[8] != 3) $stop; - if (A9[9] != 6) $stop; + a3 = '{1, 2, 3}; + a9 = {a3, 4, 5, a3, 6}; + if (a9[1] != 1) $stop; + if (a9[2] != 2) $stop; + if (a9[3] != 3) $stop; + if (a9[4] != 4) $stop; + if (a9[5] != 5) $stop; + if (a9[6] != 1) $stop; + if (a9[7] != 2) $stop; + if (a9[8] != 3) $stop; + if (a9[9] != 6) $stop; - s3 = {s0, s1, s2}; + s3 = {s0, s1, s1b}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s3[2:8] = {s0, s1[1:2], s1[3], s2[3], s2[2:1]}; + s3[2:8] = {s0, s1[1:2], s1[3], s1b[3], s1b[2:1]}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s3 = {s0, s1[1], s1[2:3], s2[3:2], s2[1]}; + s3 = {s0, s1[1], s1[2:3], s1b[3:2], s1b[1]}; if (s3[2] != s0) $stop; if (s3[3] != s1[1]) $stop; if (s3[4] != s1[2]) $stop; if (s3[5] != s1[3]) $stop; - if (s3[6] != s2[3]) $stop; - if (s3[7] != s2[2]) $stop; - if (s3[8] != s2[1]) $stop; + if (s3[6] != s1b[3]) $stop; + if (s3[7] != s1b[2]) $stop; + if (s3[8] != s1b[1]) $stop; - s4 = {s0, s1, s2}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b = {s0, s1, s1b}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; - s4[8:2] = {s0, s1[1:2], s1[3], s2[3], s2[2:1]}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b[8:2] = {s0, s1[1:2], s1[3], s1b[3], s1b[2:1]}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; - s4 = {s0, s1[1], s1[2:3], s2[3:2], s2[1]}; - if (s4[8] != s0) $stop; - if (s4[7] != s1[1]) $stop; - if (s4[6] != s1[2]) $stop; - if (s4[5] != s1[3]) $stop; - if (s4[4] != s2[3]) $stop; - if (s4[3] != s2[2]) $stop; - if (s4[2] != s2[1]) $stop; + s3b = {s0, s1[1], s1[2:3], s1b[3:2], s1b[1]}; + if (s3b[8] != s0) $stop; + if (s3b[7] != s1[1]) $stop; + if (s3b[6] != s1[2]) $stop; + if (s3b[5] != s1[3]) $stop; + if (s3b[4] != s1b[3]) $stop; + if (s3b[3] != s1b[2]) $stop; + if (s3b[2] != s1b[1]) $stop; $write("*-* All Finished *-*\n"); $finish; diff --git a/test_regress/t/t_unpacked_init.v b/test_regress/t/t_unpacked_init.v index ae7243ad1..e9d052a51 100644 --- a/test_regress/t/t_unpacked_init.v +++ b/test_regress/t/t_unpacked_init.v @@ -14,6 +14,8 @@ module t (/*AUTOARG*/); int a3[1] = '{16}; int a4[1] = {17}; + int a5[2][3] = '{'{10, 11, 12}, '{13, 14, 15}}; + initial begin `checkh(a1[0], 12); `checkh(a1[1], 13); @@ -25,6 +27,13 @@ module t (/*AUTOARG*/); `checkh(a4[0], 17); + `checkh(a5[0][0], 10); + `checkh(a5[0][1], 11); + `checkh(a5[0][2], 12); + `checkh(a5[1][0], 13); + `checkh(a5[1][1], 14); + `checkh(a5[1][2], 15); + $write("*-* All Finished *-*\n"); $finish; end From a247041cab9557c93932832f9266abd4fd88f256 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 2 Dec 2024 21:12:04 -0500 Subject: [PATCH 135/171] Internals: Refactor 713dab27 to avoid IfaceRef being known in LinkCells --- src/V3AstNodeOther.h | 6 +++--- src/V3AstNodes.cpp | 3 ++- src/V3LinkParse.cpp | 13 +++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index ec8c777e3..da584d4ef 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -2121,9 +2121,9 @@ public: bool isScBigUint() const VL_MT_STABLE; bool isScSensitive() const { return m_scSensitive; } bool isSigPublic() const; - bool isSigModPublic() const { return m_sigModPublic; } - bool isSigUserRdPublic() const { return m_sigUserRdPublic; } - bool isSigUserRWPublic() const { return m_sigUserRWPublic; } + bool isSigModPublic() const { return m_sigModPublic && !isIfaceRef(); } + bool isSigUserRdPublic() const { return m_sigUserRdPublic && !isIfaceRef(); } + bool isSigUserRWPublic() const { return m_sigUserRWPublic && !isIfaceRef(); } bool isTrace() const { return m_trace; } bool isRand() const { return m_rand.isRand(); } bool isRandC() const { return m_rand.isRandC(); } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 62596a32d..4a4620450 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -437,7 +437,8 @@ void AstNetlist::timeprecisionMerge(FileLine*, const VTimescale& value) { } bool AstVar::isSigPublic() const { - return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar())); + return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar())) + && !isIfaceRef(); } bool AstVar::isScQuad() const { return (isSc() && isQuad() && !isScBv() && !isScBigUint()); } bool AstVar::isScBv() const { diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 238d9dd49..07ea7cc14 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -430,23 +430,20 @@ class LinkParseVisitor final : public VNVisitor { VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - // Public ifacerefs aren't supported - be compatible with older parser that ignored it - if (!m_varp->isIfaceRef()) { - m_varp->sigUserRWPublic(true); - m_varp->sigModPublic(true); - } + m_varp->sigUserRWPublic(true); + m_varp->sigModPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); + m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RD) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRdPublic(true); + m_varp->sigUserRdPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_PUBLIC_FLAT_RW) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); - if (!m_varp->isIfaceRef()) m_varp->sigUserRWPublic(true); + m_varp->sigUserRWPublic(true); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); } else if (nodep->attrType() == VAttrType::VAR_ISOLATE_ASSIGNMENTS) { UASSERT_OBJ(m_varp, nodep, "Attribute not attached to variable"); From a7f8c9cc74a177d276eca458504f38cb40b187e8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 5 Dec 2024 08:54:00 -0500 Subject: [PATCH 136/171] Commentary --- docs/guide/simulating.rst | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/guide/simulating.rst b/docs/guide/simulating.rst index f62bada5c..6a3484c7f 100644 --- a/docs/guide/simulating.rst +++ b/docs/guide/simulating.rst @@ -224,14 +224,6 @@ at branches). At each such branch, a counter is incremented. At the end of a test, the counters, filename, and line number corresponding to each counter are written into the coverage file. -Verilator automatically disables coverage of branches with a $stop in -them, as it is assumed that $stop branches contain an error check that should -not occur. A :option:`/*verilator&32;coverage_block_off*/` metacomment -will perform a similar function on any code in that block or below, or -:option:`/*verilator&32;coverage_off*/` and -:option:`/*verilator&32;coverage_on*/` will disable and enable coverage -respectively around a block of code. - Verilator may over-count combinatorial (non-clocked) blocks when those blocks receive signals which have had the :option:`UNOPTFLAT` warning disabled; for the most accurate results, do not disable this warning when @@ -278,6 +270,22 @@ A :option:`/*verilator&32;coverage_off*/` signals that do not need toggle analysis, such as RAMs and register files. +.. _Suppressing Coverage: + +Suppressing Coverage +-------------------- + +Using :option:`/*verilator&32;coverage_off*/` and +:option:`/*verilator&32;coverage_on*/` around a block of code will disable +and enable coverage respectively around that block. Or, use the +:option:`coverage_block_off` configuration file option. + +Verilator automatically disables coverage of lines and branches with a +$stop in them, as it is assumed that $stop branches contain an error check +that should not occur. A :option:`/*verilator&32;coverage_block_off*/` +metacomment will perform a similar function on any code in that block or +below. + .. _Coverage Collection: Coverage Collection From 676fd3163590dc62c9121d0966857c2c4397251f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 5 Dec 2024 08:54:43 -0500 Subject: [PATCH 137/171] Commentary: Changes update --- Changes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changes b/Changes index d8a560704..ece562e22 100644 --- a/Changes +++ b/Changes @@ -146,6 +146,9 @@ Verilator 5.030 2024-10-27 * Fix build on gcc when using the Spack wrapper (#5555). [Eric Müller] * Fix enum name method (#5563). [Todd Strader] * Fix `$countbits` in assert with non-tristates (#5566). [Shou-Li Hsu] +* Fix missing VlProcess handle in coroutines with splits (#5623) (#5650). [Bartłomiej Chmiel, Antmicro Ltd.] +* Fix imported array assignment literals (#5642) (#5648). [Todd Strader] +* Fix foreach mixed array (#5655) (#5656). [Yilou Wang] Verilator 5.028 2024-08-21 From 9656311521a7fe33054a4921986fa0cf8f6c0f5f Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 6 Dec 2024 13:20:31 +0100 Subject: [PATCH 138/171] Fix error on duplicated declaration of gen block (#5663) --- src/V3LinkDot.cpp | 2 +- test_regress/t/t_duplicated_gen_blocks_bad.out | 15 +++++++++++++++ test_regress/t/t_duplicated_gen_blocks_bad.py | 16 ++++++++++++++++ test_regress/t/t_duplicated_gen_blocks_bad.v | 17 +++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 test_regress/t/t_duplicated_gen_blocks_bad.out create mode 100755 test_regress/t/t_duplicated_gen_blocks_bad.py create mode 100644 test_regress/t/t_duplicated_gen_blocks_bad.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 9a5933af2..a18cc8f39 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -280,7 +280,7 @@ public: } else if (foundp->imported()) { // From package // We don't throw VARHIDDEN as if the import is later the symbol // table's import wouldn't warn - } else if (VN_IS(nodep, Begin) && VN_IS(fnodep, Begin) + } else if (forPrimary() && VN_IS(nodep, Begin) && VN_IS(fnodep, Begin) && VN_AS(nodep, Begin)->generate()) { // Begin: ... blocks often replicate under genif/genfor, so // suppress duplicate checks. See t_gen_forif.v for an example. diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.out b/test_regress/t/t_duplicated_gen_blocks_bad.out new file mode 100644 index 000000000..5d14ab424 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.out @@ -0,0 +1,15 @@ +%Error: t/t_duplicated_gen_blocks_bad.v:11:12: Duplicate declaration of block: 'block' + : ... note: In instance 't' + 11 | begin : block + | ^~~~~ + t/t_duplicated_gen_blocks_bad.v:9:12: ... Location of original declaration + 9 | begin : block + | ^~~~~ +%Error: t/t_duplicated_gen_blocks_bad.v:15:23: Duplicate declaration of block: 'block1' + : ... note: In instance 't' + 15 | if (X > 1) begin : block1 + | ^~~~~~ + t/t_duplicated_gen_blocks_bad.v:13:23: ... Location of original declaration + 13 | if (X > 0) begin : block1 + | ^~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.py b/test_regress/t/t_duplicated_gen_blocks_bad.py new file mode 100755 index 000000000..31228c9a7 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_duplicated_gen_blocks_bad.v b/test_regress/t/t_duplicated_gen_blocks_bad.v new file mode 100644 index 000000000..43f7742a9 --- /dev/null +++ b/test_regress/t/t_duplicated_gen_blocks_bad.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + parameter X = 2; + begin : block + end + begin : block + end + if (X > 0) begin : block1 + end + if (X > 1) begin : block1 + end +endmodule From 58ddf997e3a0e1038f41e70b1e5a39018b183e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Wed, 11 Dec 2024 12:45:31 +0100 Subject: [PATCH 139/171] Improve optimization of duplicate wide expressions (#5637) Prevent inlining of expensive wide expressions in V3Gate (#5637) --- src/V3Gate.cpp | 43 ++++++++++++++++++ .../t/t_gate_inline_wide_exclude_multiple.py | 19 ++++++++ .../t/t_gate_inline_wide_exclude_multiple.v | 26 +++++++++++ .../t_gate_inline_wide_noexclude_arraysel.py | 19 ++++++++ .../t/t_gate_inline_wide_noexclude_arraysel.v | 19 ++++++++ .../t/t_gate_inline_wide_noexclude_const.py | 19 ++++++++ .../t/t_gate_inline_wide_noexclude_const.v | 19 ++++++++ ..._gate_inline_wide_noexclude_other_scope.py | 18 ++++++++ ...t_gate_inline_wide_noexclude_other_scope.v | 26 +++++++++++ .../t/t_gate_inline_wide_noexclude_sel.py | 19 ++++++++ .../t/t_gate_inline_wide_noexclude_sel.v | 44 +++++++++++++++++++ ...t_gate_inline_wide_noexclude_small_wide.py | 18 ++++++++ .../t_gate_inline_wide_noexclude_small_wide.v | 21 +++++++++ .../t/t_gate_inline_wide_noexclude_varref.py | 19 ++++++++ .../t/t_gate_inline_wide_noexclude_varref.v | 17 +++++++ 15 files changed, 346 insertions(+) create mode 100755 test_regress/t/t_gate_inline_wide_exclude_multiple.py create mode 100644 test_regress/t/t_gate_inline_wide_exclude_multiple.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_arraysel.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_arraysel.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_const.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_const.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_other_scope.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_other_scope.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_sel.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_sel.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_small_wide.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_small_wide.v create mode 100755 test_regress/t/t_gate_inline_wide_noexclude_varref.py create mode 100644 test_regress/t/t_gate_inline_wide_noexclude_varref.v diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index 1ddac0799..d5dfbaad4 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -681,8 +681,44 @@ class GateInline final { std::unordered_map m_hasPending; size_t m_statInlined = 0; // Statistic tracking - signals inlined size_t m_statRefs = 0; // Statistic tracking + size_t m_statExcluded = 0; // Statistic tracking // METHODS + static bool isCheapWide(const AstNodeExpr* exprp) { + if (const AstSel* const selp = VN_CAST(exprp, Sel)) { + if (selp->lsbConst() % VL_EDATASIZE != 0) return false; + exprp = selp->fromp(); + } + if (const AstArraySel* const aselp = VN_CAST(exprp, ArraySel)) exprp = aselp->fromp(); + return VN_IS(exprp, Const) || VN_IS(exprp, NodeVarRef); + } + static bool excludedWide(GateVarVertex* const vVtxp, const AstNodeExpr* const rhsp) { + // Handle wides with logic drivers that are too wide for V3Expand. + if (!vVtxp->varScp()->isWide() // + || vVtxp->varScp()->widthWords() <= v3Global.opt.expandLimit() // + || vVtxp->inEmpty() // + || isCheapWide(rhsp)) + return false; + + const GateLogicVertex* const lVtxp + = vVtxp->inEdges().frontp()->fromp()->as(); + + // Exclude from inlining variables READ multiple times. + // To decouple actives thus simplifying scheduling, exclude only those + // VarRefs that are referenced under the same active as they were assigned. + if (const AstActive* const primaryActivep = lVtxp->activep()) { + size_t reads = 0; + for (const V3GraphEdge& edge : vVtxp->outEdges()) { + const GateLogicVertex* const lvp = edge.top()->as(); + if (lvp->activep() != primaryActivep) continue; + + reads += edge.weight(); + if (reads > 1) return true; + } + } + return false; + } + void recordSubstitution(AstVarScope* vscp, AstNodeExpr* substp, AstNode* logicp) { m_hasPending.emplace(logicp, ++m_ord); // It's OK if already present const auto pair = m_substitutions(logicp).emplace(vscp, nullptr); @@ -777,6 +813,12 @@ class GateInline final { if (!okVisitor.isSimple()) continue; // If the varScope is already removed from logicp, no need to try substitution. if (!okVisitor.varAssigned(vVtxp->varScp())) continue; + if (excludedWide(vVtxp, okVisitor.substitutionp())) { + ++m_statExcluded; + UINFO(9, "Gate inline exclude '" << vVtxp->name() << "'" << endl); + vVtxp->clearReducible("Excluded wide"); // Check once. + continue; + } // Does it read multiple source variables? if (okVisitor.readVscps().size() > 1) { @@ -876,6 +918,7 @@ class GateInline final { ~GateInline() { V3Stats::addStat("Optimizations, Gate sigs deleted", m_statInlined); V3Stats::addStat("Optimizations, Gate inputs replaced", m_statRefs); + V3Stats::addStat("Optimizations, Gate excluded wide expressions", m_statExcluded); } public: diff --git a/test_regress/t/t_gate_inline_wide_exclude_multiple.py b/test_regress/t/t_gate_inline_wide_exclude_multiple.py new file mode 100755 index 000000000..516288695 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_exclude_multiple.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 2) +test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 4) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_exclude_multiple.v b/test_regress/t/t_gate_inline_wide_exclude_multiple.v new file mode 100644 index 000000000..5e2ae1a80 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_exclude_multiple.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +localparam N = 256; // Wider than expand limit. + +module t( + input wire [N-1:0] i, + output logic [N-1:0] o_multiple1, + output logic [N-1:0] o_multiple2, + output wire [N-1:0] o + ); + + // Exclude from inline wide expressions referenced multiple times. + wire [N-1:0] wide_multiple_assigns = N >> i; + wire [N-1:0] wide = N << i; + + for (genvar n = 0; n < N - 1; ++n) begin + assign o[n] = i[N-1-n] | wide[N-1-n]; + end + + assign o_multiple1 = wide_multiple_assigns | i + 1; + assign o_multiple2 = wide_multiple_assigns | i + 2; +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_arraysel.py b/test_regress/t/t_gate_inline_wide_noexclude_arraysel.py new file mode 100755 index 000000000..16d0c0d48 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_arraysel.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0) +test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 1) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_arraysel.v b/test_regress/t/t_gate_inline_wide_noexclude_arraysel.v new file mode 100644 index 000000000..282929316 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_arraysel.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t; + logic [255:0] arrd [0:0] = '{ 1 }; + logic [255:0] y0; + + // Do not exclude from inlining wide arraysels. + always_comb y0 = arrd[0]; + + always_comb begin + if (y0 != 1 && y0 != 0) begin + $stop; + end + end +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_const.py b/test_regress/t/t_gate_inline_wide_noexclude_const.py new file mode 100755 index 000000000..00b053a42 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_const.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0) +test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 2) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_const.v b/test_regress/t/t_gate_inline_wide_noexclude_const.v new file mode 100644 index 000000000..d45648982 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_const.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t; + logic [255:0] arrd = 256'b0; + logic [255:0] y0; + + // Do not exclude from inlining wide variables with const assignments. + always_comb y0 = 256'(arrd[0]); + + always_comb begin + if (y0 != 1 && y0 != 0) begin + $stop; + end + end +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_other_scope.py b/test_regress/t/t_gate_inline_wide_noexclude_other_scope.py new file mode 100755 index 000000000..0226ac927 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_other_scope.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_other_scope.v b/test_regress/t/t_gate_inline_wide_noexclude_other_scope.v new file mode 100644 index 000000000..2181f9504 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_other_scope.v @@ -0,0 +1,26 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +localparam N = 256; // Wider than expand limit. + +module t( + input wire [N-1:0] i, + output wire [N-1:0] o + ); + + // Do not exclude from inlining wides referenced in different scope. + wire [N-1:0] wide = N ~^ i; + + sub sub(i, wide, o); +endmodule + +module sub(input wire [N-1:0] i, input wire [N-1:0] wide, output logic [N-1:0] o); + initial begin + for (integer n = 0; n < N ; ++n) begin + o[n] = i[N-1-n] | wide[N-1-n]; + end + end +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_sel.py b/test_regress/t/t_gate_inline_wide_noexclude_sel.py new file mode 100755 index 000000000..28148d585 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_sel.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 1) +test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 9) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_sel.v b/test_regress/t/t_gate_inline_wide_noexclude_sel.v new file mode 100644 index 000000000..931ca0d62 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_sel.v @@ -0,0 +1,44 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t ( + output reg [1020:0] res1, + output reg [1020:0] res2, + output reg [1022:0] res3, + output reg [1022:0] res4 + ); + always_inline always_inline(res1, res2); + dont_inline dont_inline(res3, res4); +endmodule + +module always_inline( + output reg [1020:0] res1, + output reg [1020:0] res2 + ); + + wire [1023:0] a; + wire [478:0] b; + + assign b = a[510:32]; + assign res1 = {542'b0, b}; + assign res2 = {542'b1, b}; +endmodule + +// SEL does not have proper offset so we do not have guarantee that it will be +// emitted as '[' operator, thus we do not exclude it from inlining. +module dont_inline( + output reg [1022:0] res1, + output reg [1022:0] res2 + ); + + wire [1023:0] a; + wire [480:0] b; + + // LSB % 32 != 0 + assign b = a[510:30]; + assign res1 = {542'b0, b}; + assign res2 = {542'b1, b}; +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_small_wide.py b/test_regress/t/t_gate_inline_wide_noexclude_small_wide.py new file mode 100755 index 000000000..0226ac927 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_small_wide.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_small_wide.v b/test_regress/t/t_gate_inline_wide_noexclude_small_wide.v new file mode 100644 index 000000000..bbb3022a3 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_small_wide.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +localparam N = 65; // Wide but narrower than expand limit + +module t( + input wire [N-1:0] i, + output wire [N-1:0] o + ); + + // Do not exclude from inlining wides small enough to be handled by + // V3Expand. + wire [65:0] wide_small = N << i * i / N; + + for (genvar n = 0; n < N; ++n) begin + assign o[n] = i[n] ^ wide_small[n]; + end +endmodule diff --git a/test_regress/t/t_gate_inline_wide_noexclude_varref.py b/test_regress/t/t_gate_inline_wide_noexclude_varref.py new file mode 100755 index 000000000..bab7603d6 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_varref.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['--stats', '--expand-limit 5']) + +test.file_grep(test.stats, r'Optimizations, Gate excluded wide expressions\s+(\d+)', 0) +test.file_grep(test.stats, r'Optimizations, Gate sigs deleted\s+(\d+)', 3) + +test.passes() diff --git a/test_regress/t/t_gate_inline_wide_noexclude_varref.v b/test_regress/t/t_gate_inline_wide_noexclude_varref.v new file mode 100644 index 000000000..4b4b94d64 --- /dev/null +++ b/test_regress/t/t_gate_inline_wide_noexclude_varref.v @@ -0,0 +1,17 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t(input [255:0] clk); + // Do not exclude from inlining wide reference assignments. + mod1 mod1(clk); + mod2 mod2(clk); +endmodule + +module mod1(input [255:0] clk); +endmodule + +module mod2(input [255:0] clk); +endmodule From 6e204ed0dda3f51ccd185ff144a6d7ef5b9f1239 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 11 Dec 2024 08:52:41 -0500 Subject: [PATCH 140/171] Internals: Cleanup 'error error' on fatals --- include/verilated.cpp | 2 +- include/verilated_cov.cpp | 2 +- include/verilated_timing.cpp | 2 +- src/V3EmitCModel.cpp | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/verilated.cpp b/include/verilated.cpp index a4968ccd7..fd80ae41a 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -2650,7 +2650,7 @@ const char* VerilatedContext::timeprecisionString() const VL_MT_SAFE { } void VerilatedContext::threads(unsigned n) { - if (n == 0) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: Simulation threads must be >= 1"); + if (n == 0) VL_FATAL_MT(__FILE__, __LINE__, "", "Simulation threads must be >= 1"); if (m_threadPool) { VL_FATAL_MT( diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 412102476..6aa1ec5eb 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -233,7 +233,7 @@ private: // Little selftest #define SELF_CHECK(got, exp) \ do { \ - if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest"); \ + if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "selftest"); \ } while (0) SELF_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c"); SELF_CHECK(combineHier("a.b.c", "a.b"), "a.b*"); diff --git a/include/verilated_timing.cpp b/include/verilated_timing.cpp index f7ceec357..0724a43e9 100644 --- a/include/verilated_timing.cpp +++ b/include/verilated_timing.cpp @@ -89,7 +89,7 @@ void VlDelayScheduler::resume() { uint64_t VlDelayScheduler::nextTimeSlot() const { if (!m_queue.empty()) return m_queue.cbegin()->first; if (m_zeroDelayed.empty()) - VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: There is no next time slot scheduled"); + VL_FATAL_MT(__FILE__, __LINE__, "", "There is no next time slot scheduled"); return m_context.time(); } diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index 54f625d13..d31dc8ca6 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -473,8 +473,7 @@ class EmitCModel final : public EmitCFunc { } else { putns(modp, "bool " + topClassName() + "::eventsPending() { return false; }\n\n"); puts("uint64_t " + topClassName() + "::nextTimeSlot() {\n"); - puts("VL_FATAL_MT(__FILE__, __LINE__, \"\", \"%Error: No delays in the " - "design\");\n"); + puts("VL_FATAL_MT(__FILE__, __LINE__, \"\", \"No delays in the design\");\n"); puts("return 0;\n}\n"); } From a2f327f72961aec857e1416272cdea30ab0231ed Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 12 Dec 2024 08:16:19 -0500 Subject: [PATCH 141/171] Support `extern constraint` --- Changes | 2 +- src/V3AstNodeOther.h | 29 +++++--- src/V3AstNodes.cpp | 21 +++++- src/V3LinkDot.cpp | 70 ++++++++++++++++--- src/V3LinkResolve.cpp | 10 +++ src/verilog.y | 26 +++---- test_regress/t/t_constraint.v | 2 + test_regress/t/t_constraint_extern.py | 21 ++++++ test_regress/t/t_constraint_extern.v | 41 +++++++++++ test_regress/t/t_constraint_extern_bad.out | 7 ++ ...e_extern.py => t_constraint_extern_bad.py} | 4 +- test_regress/t/t_constraint_extern_bad.v | 14 ++++ test_regress/t/t_constraint_json_only.out | 4 +- test_regress/t/t_constraint_nosolver_bad.out | 2 +- test_regress/t/t_json_only_tag.out | 2 +- test_regress/t/t_randomize_extern.out | 8 --- test_regress/t/t_randomize_extern.v | 42 ----------- 17 files changed, 215 insertions(+), 90 deletions(-) create mode 100755 test_regress/t/t_constraint_extern.py create mode 100644 test_regress/t/t_constraint_extern.v create mode 100644 test_regress/t/t_constraint_extern_bad.out rename test_regress/t/{t_randomize_extern.py => t_constraint_extern_bad.py} (81%) create mode 100644 test_regress/t/t_constraint_extern_bad.v delete mode 100644 test_regress/t/t_randomize_extern.out delete mode 100644 test_regress/t/t_randomize_extern.v diff --git a/Changes b/Changes index ece562e22..0ced35e20 100644 --- a/Changes +++ b/Changes @@ -19,7 +19,7 @@ Verilator 5.031 devel * Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill] * Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.] * Support `default disable iff` and `$inferred_disable` (#4016). [Srinivasan Venkataramanan] -* Support `pure constraint`. +* Support `extern constraint` and `pure constraint`. * Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). * Add `--no-std-package` as subset-alias of `--no-std` (#5607). * Add `lint_off --contents` in configuration files (#5606). diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index da584d4ef..7dce283ac 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -68,8 +68,6 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode { bool m_taskPublic : 1; // Public task bool m_attrIsolateAssign : 1; // User isolate_assignments attribute bool m_classMethod : 1; // Class method - bool m_externProto : 1; // Extern prototype - bool m_externDef : 1; // Extern definition bool m_prototype : 1; // Just a prototype bool m_dpiExport : 1; // DPI exported bool m_dpiImport : 1; // DPI imported @@ -77,6 +75,8 @@ class AstNodeFTask VL_NOT_FINAL : public AstNode { bool m_dpiOpenChild : 1; // DPI import open array child wrapper bool m_dpiTask : 1; // DPI import task (vs. void function) bool m_isConstructor : 1; // Class constructor + bool m_isExternProto : 1; // Extern prototype + bool m_isExternDef : 1; // Extern definition bool m_isHideLocal : 1; // Verilog local bool m_isHideProtected : 1; // Verilog protected bool m_dpiPure : 1; // DPI import pure (vs. virtual pure) @@ -97,8 +97,6 @@ protected: , m_taskPublic{false} , m_attrIsolateAssign{false} , m_classMethod{false} - , m_externProto{false} - , m_externDef{false} , m_prototype{false} , m_dpiExport{false} , m_dpiImport{false} @@ -106,6 +104,8 @@ protected: , m_dpiOpenChild{false} , m_dpiTask{false} , m_isConstructor{false} + , m_isExternProto{false} + , m_isExternDef{false} , m_isHideLocal{false} , m_isHideProtected{false} , m_dpiPure{false} @@ -144,10 +144,10 @@ public: void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; } bool classMethod() const { return m_classMethod; } void classMethod(bool flag) { m_classMethod = flag; } - bool isExternProto() const { return m_externProto; } - void isExternProto(bool flag) { m_externProto = flag; } - bool isExternDef() const { return m_externDef; } - void isExternDef(bool flag) { m_externDef = flag; } + bool isExternProto() const { return m_isExternProto; } + void isExternProto(bool flag) { m_isExternProto = flag; } + bool isExternDef() const { return m_isExternDef; } + void isExternDef(bool flag) { m_isExternDef = flag; } bool prototype() const { return m_prototype; } void prototype(bool flag) { m_prototype = flag; } bool dpiExport() const { return m_dpiExport; } @@ -1021,7 +1021,12 @@ public: class AstConstraint final : public AstNode { // Constraint // @astgen op1 := itemsp : List[AstNode] + // @astgen op2 := classOrPackagep : Optional[AstNode] string m_name; // Name of constraint + VBaseOverride m_baseOverride; // BaseOverride (inital/final/extends) + bool m_isExternDef = false; // Extern prototype definition + bool m_isExternExplicit = false; // Explicit prototype declaration (has extern) + bool m_isExternProto = false; // Prototype declaration (implicit or explicit) bool m_isKwdPure = false; // Pure constraint bool m_isStatic = false; // Static constraint public: @@ -1038,6 +1043,14 @@ public: bool isPredictOptimizable() const override { return false; } bool maybePointedTo() const override VL_MT_SAFE { return true; } bool sameNode(const AstNode* /*samep*/) const override { return true; } + void baseOverride(const VBaseOverride& flag) { m_baseOverride = flag; } + VBaseOverride baseOverride() const { return m_baseOverride; } + bool isExternDef() const { return m_isExternDef; } + void isExternDef(bool flag) { m_isExternDef = flag; } + void isExternExplicit(bool flag) { m_isExternExplicit = flag; } + bool isExternExplicit() const { return m_isExternExplicit; } + void isExternProto(bool flag) { m_isExternProto = flag; } + bool isExternProto() const { return m_isExternProto; } void isKwdPure(bool flag) { m_isKwdPure = flag; } bool isKwdPure() const { return m_isKwdPure; } void isStatic(bool flag) { m_isStatic = flag; } diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 4a4620450..0e1a02143 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -368,12 +368,21 @@ void AstConsQueue::dumpJson(std::ostream& str) const { } void AstConstraint::dump(std::ostream& str) const { this->AstNode::dump(str); + if (isExternDef()) str << " [EXTDEF]"; + if (isExternExplicit()) + str << " [PROTOEXP]"; + else if (isExternProto()) + str << " [PROTO]"; if (isKwdPure()) str << " [KWDPURE]"; if (isStatic()) str << " [STATIC]"; } void AstConstraint::dumpJson(std::ostream& str) const { + dumpJsonBoolFunc(str, isExternDef); + dumpJsonBoolFunc(str, isExternExplicit); + dumpJsonBoolFunc(str, isExternProto); dumpJsonBoolFunc(str, isKwdPure); dumpJsonBoolFunc(str, isStatic); + if (baseOverride().isAny()) dumpJsonStr(str, "baseOverride", baseOverride().ascii()); dumpJsonGen(str); } void AstConstraintExpr::dump(std::ostream& str) const { @@ -1657,9 +1666,11 @@ void AstCellInlineScope::dumpJson(std::ostream& str) const { dumpJsonGen(str); } bool AstClass::isCacheableChild(const AstNode* nodep) { - return (VN_IS(nodep, Var) || VN_IS(nodep, Constraint) || VN_IS(nodep, EnumItemRef) - || (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto()) - || VN_IS(nodep, CFunc)); + return VN_IS(nodep, Var) + || (VN_IS(nodep, Constraint) && !VN_AS(nodep, Constraint)->isExternProto()) + || VN_IS(nodep, EnumItemRef) + || (VN_IS(nodep, NodeFTask) && !VN_AS(nodep, NodeFTask)->isExternProto()) + || VN_IS(nodep, CFunc); } AstClass* AstClass::baseMostClassp() { AstClass* basep = this; @@ -2652,6 +2663,8 @@ void AstNodeFTask::dump(std::ostream& str) const { if (dpiImport()) str << " [DPII]"; if (dpiOpenChild()) str << " [DPIOPENCHILD]"; if (dpiOpenParent()) str << " [DPIOPENPARENT]"; + if (isExternDef()) str << " [EXTDEF]"; + if (isExternProto()) str << " [EXTPROTO]"; if (prototype()) str << " [PROTOTYPE]"; if (pureVirtual()) str << " [PUREVIRTUAL]"; if (recursive()) str << " [RECURSIVE]"; @@ -2689,6 +2702,8 @@ void AstNodeFTask::dumpJson(std::ostream& str) const { dumpJsonBoolFunc(str, dpiImport); dumpJsonBoolFunc(str, dpiOpenChild); dumpJsonBoolFunc(str, dpiOpenParent); + dumpJsonBoolFunc(str, isExternDef); + dumpJsonBoolFunc(str, isExternProto); dumpJsonBoolFunc(str, prototype); dumpJsonBoolFunc(str, recursive); dumpJsonBoolFunc(str, taskPublic); diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index a18cc8f39..d0cdc3903 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1207,8 +1207,7 @@ class LinkDotFindVisitor final : public VNVisitor { m_classOrPackagep = VN_AS(m_curSymp->nodep(), Class); } // Create symbol table for the task's vars - const string name - = std::string{nodep->isExternProto() ? "extern " : ""} + nodep->name(); + const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name(); m_curSymp = m_statep->insertBlock(m_curSymp, name, nodep, m_classOrPackagep); m_curSymp->fallbackp(upSymp); // Convert the func's range to the output variable @@ -1299,7 +1298,35 @@ class LinkDotFindVisitor final : public VNVisitor { } void visit(AstConstraint* nodep) override { VL_RESTORER(m_curSymp); - m_curSymp = m_statep->insertBlock(m_curSymp, nodep->name(), nodep, m_classOrPackagep); + // Change to appropriate package if extern declaration (vs definition) + VSymEnt* upSymp = m_curSymp; + if (nodep->classOrPackagep()) { + AstClassOrPackageRef* const cpackagerefp + = VN_CAST(nodep->classOrPackagep(), ClassOrPackageRef); + if (!cpackagerefp) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: extern constraint definition with class-in-class"); + } else { + if (!cpackagerefp->classOrPackageSkipp()) { + m_statep->resolveClassOrPackage(m_curSymp, cpackagerefp, false, + "External definition :: reference"); + } + AstClass* const classp = VN_CAST(cpackagerefp->classOrPackageSkipp(), Class); + if (!classp) { + nodep->v3error("Extern declaration's scope is not a defined class"); + } else { + m_curSymp = m_statep->getNodeSym(classp); + upSymp = m_curSymp; + // Move it to proper spot under the target class + nodep->unlinkFrBack(); + classp->addStmtsp(nodep); + nodep->classOrPackagep()->unlinkFrBack()->deleteTree(); + } + } + } + // Set the class as package for iteration + const string name = (nodep->isExternProto() ? "extern "s : ""s) + nodep->name(); + m_curSymp = m_statep->insertBlock(upSymp, name, nodep, m_classOrPackagep); iterateChildren(nodep); } void visit(AstVar* nodep) override { @@ -3287,6 +3314,31 @@ class LinkDotResolveVisitor final : public VNVisitor { UINFO(9, indent() << "set sym " << m_ds.ascii() << endl); } } + void visit(AstConstraint* nodep) override { + LINKDOT_VISIT_START(); + UINFO(5, indent() << "visit " << nodep << endl); + checkNoDot(nodep); + if (nodep->isExternDef()) { + if (const VSymEnt* const foundp + = m_curSymp->findIdFallback("extern " + nodep->name())) { + const AstConstraint* const protop = VN_AS(foundp->nodep(), Constraint); + // Copy specifiers. + // External definition cannot have any specifiers, so no value will be overwritten. + nodep->isStatic(protop->isStatic()); + } else { + nodep->v3error("extern not found that declares " + nodep->prettyNameQ()); + } + } + if (nodep->isExternProto()) { + if (!m_curSymp->findIdFallback(nodep->name()) && !nodep->isExternExplicit()) { + nodep->v3error("Definition not found for extern " + nodep->prettyNameQ()); + } + } + VL_RESTORER(m_curSymp); + VL_RESTORER(m_ds); + m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); + iterateChildren(nodep); + } void visit(AstConstraintRef* nodep) override { if (nodep->user3SetOnce()) return; LINKDOT_VISIT_START(); @@ -3819,14 +3871,14 @@ class LinkDotResolveVisitor final : public VNVisitor { if (nodep->isExternDef()) { if (const VSymEnt* const foundp = m_curSymp->findIdFallback("extern " + nodep->name())) { - const AstNodeFTask* const funcProtop = VN_AS(foundp->nodep(), NodeFTask); + const AstNodeFTask* const protop = VN_AS(foundp->nodep(), NodeFTask); // Copy specifiers. // External definition cannot have any specifiers, so no value will be overwritten. - nodep->isHideLocal(funcProtop->isHideLocal()); - nodep->isHideProtected(funcProtop->isHideProtected()); - nodep->isStatic(funcProtop->isStatic()); - nodep->isVirtual(funcProtop->isVirtual()); - nodep->lifetime(funcProtop->lifetime()); + nodep->isHideLocal(protop->isHideLocal()); + nodep->isHideProtected(protop->isHideProtected()); + nodep->isStatic(protop->isStatic()); + nodep->isVirtual(protop->isVirtual()); + nodep->lifetime(protop->lifetime()); } else { nodep->v3error("extern not found that declares " + nodep->prettyNameQ()); } diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 58af8051c..d6d70fef2 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -72,6 +72,16 @@ class LinkResolveVisitor final : public VNVisitor { m_classp = nodep; iterateChildren(nodep); } + void visit(AstConstraint* nodep) override { + // V3LinkDot moved the isExternDef into the class, the extern proto was + // checked to exist, and now isn't needed + nodep->isExternDef(false); + if (nodep->isExternProto()) { + VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); + return; + } + iterateChildren(nodep); + } void visit(AstInitialAutomatic* nodep) override { iterateChildren(nodep); // Initial assignments under function/tasks can just be simple diff --git a/src/verilog.y b/src/verilog.y index 0b761d24d..ac6b34010 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -4181,7 +4181,6 @@ function_subroutine_callNoMethod: // IEEE: function_subroutine // // We implement randomize as a normal funcRef, since randomize isn't a keyword // // Note yNULL is already part of expressions, so they come for free | funcRef yWITH__CUR constraint_block { $$ = new AstWithParse{$2, $1, $3}; } - | funcRef yWITH__CUR '{' '}' { $$ = new AstWithParse{$2, $1, nullptr}; } ; system_t_call: // IEEE: system_tf_call (as task) @@ -7418,17 +7417,16 @@ memberQualOne: // IEEE: property_qualifier + me class_constraint: // ==IEEE: class_constraint // // IEEE: constraint_declaration constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew constraint_block - { $$ = $4; $$->isStatic($1); $$->addItemsp($5); SYMP->popScope($$); } - | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew '{' '}' - { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } + { $$ = $4; $$->isStatic($1); $$->baseOverride($3); $$->addItemsp($5); SYMP->popScope($$); } // // IEEE: constraint_prototype + constraint_prototype_qualifier | constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';' - { $$ = $4; $$->isStatic($1); SYMP->popScope($$); } - | yEXTERN constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $4; $$->isStatic($1); SYMP->popScope($4); - BBUNSUP($1, "Unsupported: extern constraint"); } + { $$ = $4; $$->isStatic($1); $$->baseOverride($3); + $$->isExternProto(true); SYMP->popScope($$); } + | yEXTERN constraintStaticE yCONSTRAINT dynamic_override_specifiersE constraintIdNew ';' + { $$ = $5; $$->isStatic($2); $$->baseOverride($4); + $$->isExternProto(true); $$->isExternExplicit(true); SYMP->popScope($$); } | yPURE constraintStaticE yCONSTRAINT constraintIdNew ';' - { $$ = $4; $$->isKwdPure($1); $$->isStatic($1); SYMP->popScope($4); } + { $$ = $4; $$->isKwdPure($1); $$->isStatic($2); SYMP->popScope($4); } ; constraintIdNew: // IEEE: id part of class_constraint @@ -7438,7 +7436,8 @@ constraintIdNew: // IEEE: id part of class_constraint ; constraint_block: // ==IEEE: constraint_block - '{' constraint_block_itemList '}' { $$ = $2; } + '{' '}' { $$ = nullptr; } + | '{' constraint_block_itemList '}' { $$ = $2; } // | '{' error '}' { $$ = nullptr; } | '{' constraint_block_itemList error '}' { $$ = $2; } @@ -7529,9 +7528,10 @@ dist_item: // ==IEEE: dist_item + dist_weight $$ = nullptr; } ; -extern_constraint_declaration: // ==IEEE: extern_constraint_declaration - constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE idAny constraint_block - { $$ = nullptr; BBUNSUP($2, "Unsupported: extern constraint"); } +extern_constraint_declaration: // ==IEEE: extern_constraint_declaration + constraintStaticE yCONSTRAINT dynamic_override_specifiersE packageClassScopeE constraintIdNew constraint_block + { $$ = $5; $$->isStatic($1); $$->isExternDef(true); + $$->baseOverride($3); $$->classOrPackagep($4); $$->addItemsp($6); SYMP->popScope($5); } ; constraintStaticE: // IEEE: part of extern_constraint_declaration diff --git a/test_regress/t/t_constraint.v b/test_regress/t/t_constraint.v index dd700f2d9..b30f4847a 100644 --- a/test_regress/t/t_constraint.v +++ b/test_regress/t/t_constraint.v @@ -9,6 +9,8 @@ class Packet; constraint a { one > 0 && one < 2; } + constraint empty { } + endclass module t (/*AUTOARG*/); diff --git a/test_regress/t/t_constraint_extern.py b/test_regress/t/t_constraint_extern.py new file mode 100755 index 000000000..dbae8a1dc --- /dev/null +++ b/test_regress/t/t_constraint_extern.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile(verilator_flags2=['-Wno-CONSTRAINTIGN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_constraint_extern.v b/test_regress/t/t_constraint_extern.v new file mode 100644 index 000000000..8a7f4602c --- /dev/null +++ b/test_regress/t/t_constraint_extern.v @@ -0,0 +1,41 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Packet; + rand int one; + rand int two; + + extern function void f(); + constraint cone; + extern constraint ctwo; + extern constraint cmissing; // Ok per IEEE 1800-2023 18.5.1 + +endclass + +constraint Packet::cone { one > 0 && one < 2; } + +constraint Packet::ctwo { two > 1 && two < 3; } + +function void Packet::f(); +endfunction + +module t (/*AUTOARG*/); + + Packet p; + + int v; + + initial begin + p = new; + v = p.randomize(); + if (v != 1) $stop; + if (p.one != 1) $stop; + if (p.two != 2) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_constraint_extern_bad.out b/test_regress/t/t_constraint_extern_bad.out new file mode 100644 index 000000000..da6dfe795 --- /dev/null +++ b/test_regress/t/t_constraint_extern_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_extern_bad.v:8:15: Definition not found for extern 'missing_bad' + 8 | constraint missing_bad; + | ^~~~~~~~~~~ +%Error: t/t_constraint_extern_bad.v:11:20: extern not found that declares 'missing_extern' + 11 | constraint Packet::missing_extern { } + | ^~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_extern.py b/test_regress/t/t_constraint_extern_bad.py similarity index 81% rename from test_regress/t/t_randomize_extern.py rename to test_regress/t/t_constraint_extern_bad.py index e33e10acf..30c3d4f77 100755 --- a/test_regress/t/t_randomize_extern.py +++ b/test_regress/t/t_constraint_extern_bad.py @@ -9,8 +9,8 @@ import vltest_bootstrap -test.scenarios('vlt') +test.scenarios('linter') -test.lint(fails=True, expect_filename=test.golden_filename) +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) test.passes() diff --git a/test_regress/t/t_constraint_extern_bad.v b/test_regress/t/t_constraint_extern_bad.v new file mode 100644 index 000000000..ebeab9acf --- /dev/null +++ b/test_regress/t/t_constraint_extern_bad.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Packet; + constraint missing_bad; +endclass + +constraint Packet::missing_extern { } + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_constraint_json_only.out b/test_regress/t/t_constraint_json_only.out index ae7c64ed3..a146d88be 100644 --- a/test_regress/t/t_constraint_json_only.out +++ b/test_regress/t/t_constraint_json_only.out @@ -27,7 +27,7 @@ {"type":"VAR","name":"if_state_ok","addr":"(W)","loc":"d,13:13,13:24","dtypep":"(U)","origName":"if_state_ok","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"array","addr":"(X)","loc":"d,15:13,15:18","dtypep":"(Y)","origName":"array","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, {"type":"VAR","name":"state","addr":"(Z)","loc":"d,17:11,17:16","dtypep":"(M)","origName":"state","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal", + {"type":"FUNC","name":"strings_equal","addr":"(AB)","loc":"d,61:17,61:30","dtypep":"(U)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"strings_equal", "fvarp": [ {"type":"VAR","name":"strings_equal","addr":"(BB)","loc":"d,61:17,61:30","dtypep":"(U)","origName":"strings_equal","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"MEMBER","dtypeName":"bit","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"classOrPackagep": [], @@ -48,7 +48,7 @@ {"type":"VARREF","name":"strings_equal","addr":"(JB)","loc":"d,62:7,62:13","dtypep":"(U)","access":"WR","varp":"(BB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": []} ],"scopeNamep": []}, - {"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []}, + {"type":"FUNC","name":"new","addr":"(KB)","loc":"d,7:1,7:6","dtypep":"(LB)","method":true,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"new","fvarp": [],"classOrPackagep": [],"stmtsp": [],"scopeNamep": []}, {"type":"VAR","name":"constraint","addr":"(MB)","loc":"d,7:1,7:6","dtypep":"(NB)","origName":"constraint","isSc":false,"isPrimaryIO":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"attrClocker":"UNKNOWN","lifetime":"NONE","varType":"MEMBER","dtypeName":"VlRandomizer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"activesp": [],"extendsp": []} ],"activesp": []} diff --git a/test_regress/t/t_constraint_nosolver_bad.out b/test_regress/t/t_constraint_nosolver_bad.out index 9b379f091..2f4435757 100644 --- a/test_regress/t/t_constraint_nosolver_bad.out +++ b/test_regress/t/t_constraint_nosolver_bad.out @@ -3,5 +3,5 @@ Process::open: execvp(someimaginarysolver): No such file or directory %Warning: Unable to communicate with SAT solver, please check its installation or specify a different one in VERILATOR_SOLVER environment variable. ... Tried: $ someimaginarysolver -%Error: t/t_constraint.v:23: Verilog $stop +%Error: t/t_constraint.v:25: Verilog $stop Aborting... diff --git a/test_regress/t/t_json_only_tag.out b/test_regress/t/t_json_only_tag.out index af48c3d40..cb03e77cd 100644 --- a/test_regress/t/t_json_only_tag.out +++ b/test_regress/t/t_json_only_tag.out @@ -17,7 +17,7 @@ "lhsp": [ {"type":"VARREF","name":"dotted","addr":"(X)","loc":"d,33:16,33:22","dtypep":"(S)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": [],"strengthSpecp": []}, - {"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f", + {"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f", "fvarp": [ {"type":"VAR","name":"f","addr":"(Z)","loc":"d,35:13,35:14","dtypep":"(G)","origName":"f","isSc":false,"isPrimaryIO":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isUsedClock":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"attrClocker":"UNKNOWN","lifetime":"VAUTOM","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} ],"classOrPackagep": [], diff --git a/test_regress/t/t_randomize_extern.out b/test_regress/t/t_randomize_extern.out deleted file mode 100644 index 91ae91a9d..000000000 --- a/test_regress/t/t_randomize_extern.out +++ /dev/null @@ -1,8 +0,0 @@ -%Error-UNSUPPORTED: t/t_randomize_extern.v:17:4: Unsupported: extern constraint - 17 | extern constraint ex; - | ^~~~~~ - ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error-UNSUPPORTED: t/t_randomize_extern.v:21:1: Unsupported: extern constraint - 21 | constraint Packet::ex { header == 2; } - | ^~~~~~~~~~ -%Error: Exiting due to diff --git a/test_regress/t/t_randomize_extern.v b/test_regress/t/t_randomize_extern.v deleted file mode 100644 index cc74f0323..000000000 --- a/test_regress/t/t_randomize_extern.v +++ /dev/null @@ -1,42 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2020 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -class Base; - pure constraint pur; -endclass - -class Packet extends Base; - rand int header; - rand int length; - - constraint pur { length == 3; } - - extern constraint ex; - -endclass - -constraint Packet::ex { header == 2; } - -module t (/*AUTOARG*/); - - Packet p; - - initial begin - - int v; - v = p.randomize(); - if (v != 1) $stop; - if (p.header != 2) $stop; - if (p.length != 3) $stop; - v = p.randomize(1); - if (v != 1) $stop; - if (p.header != 2) $stop; - if (p.length != 3) $stop; - - $write("*-* All Finished *-*\n"); - $finish; - end -endmodule From 03e8ef0b0fbe8ff7f572e4e61e1f6c1712f5133d Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Thu, 12 Dec 2024 14:51:48 +0100 Subject: [PATCH 142/171] Fix wildcard equality and inside operators for non-fourstate expressions (#5673) --- src/V3Tristate.cpp | 6 +++--- src/V3Unknown.cpp | 8 +++++--- test_regress/t/t_eq_wild.py | 18 ++++++++++++++++++ test_regress/t/t_eq_wild.v | 21 +++++++++++++++++++++ test_regress/t/t_eq_wild_unsup.out | 6 ++++++ test_regress/t/t_eq_wild_unsup.py | 16 ++++++++++++++++ test_regress/t/t_eq_wild_unsup.v | 19 +++++++++++++++++++ test_regress/t/t_inside_queue_elem.py | 18 ++++++++++++++++++ test_regress/t/t_inside_queue_elem.v | 18 ++++++++++++++++++ 9 files changed, 124 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_eq_wild.py create mode 100644 test_regress/t/t_eq_wild.v create mode 100644 test_regress/t/t_eq_wild_unsup.out create mode 100755 test_regress/t/t_eq_wild_unsup.py create mode 100644 test_regress/t/t_eq_wild_unsup.v create mode 100755 test_regress/t/t_inside_queue_elem.py create mode 100644 test_regress/t/t_inside_queue_elem.v diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 950de4da3..0846b085a 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -1412,9 +1412,9 @@ class TristateVisitor final : public TristateBaseVisitor { } } void visitEqNeqWild(AstNodeBiop* nodep) { - if (!VN_IS(nodep->rhsp(), Const)) { - nodep->v3warn(E_UNSUPPORTED, // Says spac. - "Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); + if (!VN_IS(nodep->rhsp(), Const) && nodep->rhsp()->dtypep()->isFourstate()) { + nodep->v3warn(E_UNSUPPORTED, + "Unsupported: RHS of ==? or !=? is fourstate but not a constant"); // rhs we want to keep X/Z intact, so otherwise ignore } iterateAndNextNull(nodep->lhsp()); diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index e649c02cd..258fa5ab1 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -237,9 +237,11 @@ class UnknownVisitor final : public VNVisitor { AstNodeExpr* const rhsp = nodep->rhsp()->unlinkFrBack(); AstNodeExpr* newp; if (!VN_IS(rhsp, Const)) { - nodep->v3warn(E_UNSUPPORTED, "Unsupported: RHS of ==? or !=? must be " - "constant to be synthesizable"); // Says spec. - // Replace with anything that won't cause more errors + if (rhsp->dtypep()->isFourstate()) { + nodep->v3warn( + E_UNSUPPORTED, + "Unsupported: RHS of ==? or !=? is fourstate but not a constant"); + } newp = new AstEq{nodep->fileline(), lhsp, rhsp}; } else { // X or Z's become mask, ala case statements. diff --git a/test_regress/t/t_eq_wild.py b/test_regress/t/t_eq_wild.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_eq_wild.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_eq_wild.v b/test_regress/t/t_eq_wild.v new file mode 100644 index 000000000..7777eb6a3 --- /dev/null +++ b/test_regress/t/t_eq_wild.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +function bit get_1_or_0(bit get_1); + return get_1 ? 1'b1 : 1'b0; +endfunction + +module t (/*AUTOARG*/); + + initial begin + if (get_1_or_0(0) ==? get_1_or_0(1)) $stop; + if (!(get_1_or_0(0) !=? get_1_or_0(1))) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_eq_wild_unsup.out b/test_regress/t/t_eq_wild_unsup.out new file mode 100644 index 000000000..94c1a1f65 --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.out @@ -0,0 +1,6 @@ +%Error-UNSUPPORTED: t/t_eq_wild_unsup.v:13:13: Unsupported: RHS of ==? or !=? is fourstate but not a constant + : ... note: In instance 't' + 13 | if (1 ==? get_x_or_0(0)) $stop; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: Exiting due to diff --git a/test_regress/t/t_eq_wild_unsup.py b/test_regress/t/t_eq_wild_unsup.py new file mode 100755 index 000000000..e33e10acf --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_eq_wild_unsup.v b/test_regress/t/t_eq_wild_unsup.v new file mode 100644 index 000000000..9e7f8b7c6 --- /dev/null +++ b/test_regress/t/t_eq_wild_unsup.v @@ -0,0 +1,19 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +function logic get_x_or_0(logic get_x); + return get_x ? 1'bx : 1'b0; +endfunction + +module t; + initial begin + if (1 ==? get_x_or_0(0)) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_inside_queue_elem.py b/test_regress/t/t_inside_queue_elem.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_inside_queue_elem.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_inside_queue_elem.v b/test_regress/t/t_inside_queue_elem.v new file mode 100644 index 000000000..2854757bd --- /dev/null +++ b/test_regress/t/t_inside_queue_elem.v @@ -0,0 +1,18 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/); + + initial begin + int q[$] = {1, 2}; + if (!(1 inside {q[0], q[1]})) $stop; + if (3 inside {q[0], q[1]}) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From 32f9cf072b208d12010a132732190d29792cb7c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Thu, 12 Dec 2024 17:25:19 +0100 Subject: [PATCH 143/171] Fix hierarchical verilation for projects with dot-f dependency lists (#5199) (#5669) --- src/V3HierBlock.cpp | 6 ++-- src/V3Options.cpp | 11 +++--- src/V3Options.h | 2 +- test_regress/t/t_hier_block_import.py | 34 +++++++++++++++++++ test_regress/t/t_hier_block_import.v | 30 ++++++++++++++++ .../t_hier_block_import.vh | 13 +++++++ .../t_hier_block_import_args.f | 11 ++++++ .../t_hier_block_import_def.vh | 16 +++++++++ .../t_hier_block_import_subA.v | 11 ++++++ .../t_hier_block_import_subB.v | 12 +++++++ .../t_hier_block_import_subsub.v | 15 ++++++++ test_regress/t/t_hier_block_import_cmake.py | 34 +++++++++++++++++++ 12 files changed, 187 insertions(+), 8 deletions(-) create mode 100755 test_regress/t/t_hier_block_import.py create mode 100644 test_regress/t/t_hier_block_import.v create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import.vh create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import_args.f create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import_def.vh create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import_subA.v create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import_subB.v create mode 100644 test_regress/t/t_hier_block_import/t_hier_block_import_subsub.v create mode 100755 test_regress/t/t_hier_block_import_cmake.py diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index 853bc41eb..b9e985837 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -115,6 +115,8 @@ static void V3HierWriteCommonInputs(const V3HierBlock* hblockp, std::ostream* of if (hblockp) topModuleFile = hblockp->vFileIfNecessary(); if (!forCMake) { if (!topModuleFile.empty()) *of << topModuleFile << "\n"; + const V3StringList& vFiles = v3Global.opt.vFiles(); + for (const string& i : vFiles) *of << i << "\n"; } const V3StringSet& libraryFiles = v3Global.opt.libraryFiles(); for (const string& i : libraryFiles) { @@ -253,7 +255,7 @@ void V3HierBlock::writeCommandArgsFile(bool forCMake) const { for (const string& opt : commandOpts) *of << opt << "\n"; *of << hierBlockArgs().front() << "\n"; for (const auto& hierblockp : m_children) *of << hierblockp->hierBlockArgs().front() << "\n"; - *of << v3Global.opt.allArgsStringForHierBlock(false, forCMake) << "\n"; + *of << v3Global.opt.allArgsStringForHierBlock(false) << "\n"; } string V3HierBlock::commandArgsFilename(bool forCMake) const { @@ -477,7 +479,7 @@ void V3HierBlockPlan::writeCommandArgsFiles(bool forCMake) const { } *of << "--threads " << cvtToStr(v3Global.opt.threads()) << "\n"; *of << (v3Global.opt.systemC() ? "--sc" : "--cc") << "\n"; - *of << v3Global.opt.allArgsStringForHierBlock(true, forCMake) << "\n"; + *of << v3Global.opt.allArgsStringForHierBlock(true) << "\n"; } string V3HierBlockPlan::topCommandArgsFilename(bool forCMake) { diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 422c09a30..8131f3c6e 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -412,7 +412,7 @@ string V3Options::allArgsString() const VL_MT_SAFE { } // Delete some options for Verilation of the hierarchical blocks. -string V3Options::allArgsStringForHierBlock(bool forTop, bool forCMake) const { +string V3Options::allArgsStringForHierBlock(bool forTop) const { std::set vFiles; for (const auto& vFile : m_vFiles) vFiles.insert(vFile); string out; @@ -443,7 +443,7 @@ string V3Options::allArgsStringForHierBlock(bool forTop, bool forCMake) const { continue; } } else { // Not an option - if ((forCMake && vFiles.find(arg) != vFiles.end()) // Remove HDL + if (vFiles.find(arg) != vFiles.end() // Remove HDL || m_cppFiles.find(arg) != m_cppFiles.end()) { // Remove C++ continue; } @@ -549,9 +549,10 @@ string V3Options::filePathCheckOneDir(const string& modname, const string& dirna // 3: Delete the option and its argument if it is a number int V3Options::stripOptionsForChildRun(const string& opt, bool forTop) { if (opt == "j") return 3; - if (opt == "Mdir" || opt == "clk" || opt == "lib-create" || opt == "f" || opt == "v" - || opt == "l2-name" || opt == "mod-prefix" || opt == "prefix" || opt == "protect-lib" - || opt == "protect-key" || opt == "threads" || opt == "top-module") { + if (opt == "Mdir" || opt == "clk" || opt == "lib-create" || opt == "f" || opt == "F" + || opt == "v" || opt == "l2-name" || opt == "mod-prefix" || opt == "prefix" + || opt == "protect-lib" || opt == "protect-key" || opt == "threads" + || opt == "top-module") { return 2; } if (opt == "build" || (!forTop && (opt == "cc" || opt == "exe" || opt == "sc")) diff --git a/src/V3Options.h b/src/V3Options.h index a1e9b1b0c..e1486aeda 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -727,7 +727,7 @@ public: string allArgsString() const VL_MT_SAFE; ///< Return all passed arguments as simple string // Return options for child hierarchical blocks when forTop==false, otherwise returns args for // the top module. - string allArgsStringForHierBlock(bool forTop, bool forCMake) const; + string allArgsStringForHierBlock(bool forTop) const; void parseOpts(FileLine* fl, int argc, char** argv) VL_MT_DISABLED; void parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv) VL_MT_DISABLED; void parseOptsFile(FileLine* fl, const string& filename, bool rel) VL_MT_DISABLED; diff --git a/test_regress/t/t_hier_block_import.py b/test_regress/t/t_hier_block_import.py new file mode 100755 index 000000000..d9142462d --- /dev/null +++ b/test_regress/t/t_hier_block_import.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt_all') + +# stats will be deleted but generation will be skipped if libs of hierarchical blocks exist. +test.clean_objs() + +test.setenv('TEST_ROOT', test.t_dir + "/t_hier_block_import") + +# CI environment offers 2 VCPUs, 2 thread setting causes the following warning. +# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads. +# So use 6 threads here though it's not optimal in performance, but ok. + +test.compile(verilator_flags2=[ + '$TEST_ROOT/t_hier_block_import_def.vh', '-f $TEST_ROOT/t_hier_block_import_args.f', + '-I$TEST_ROOT' +], + threads=(6 if test.vltmt else 1)) + +test.execute() + +test.file_grep(test.obj_dir + "/VsubA/subA.sv", r'^module\s+(\S+)\s+', "subA") +test.file_grep(test.stats, r'HierBlock,\s+Hierarchical blocks\s+(\d+)', 2) + +test.passes() diff --git a/test_regress/t/t_hier_block_import.v b/test_regress/t/t_hier_block_import.v new file mode 100644 index 000000000..c2ad81e44 --- /dev/null +++ b/test_regress/t/t_hier_block_import.v @@ -0,0 +1,30 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 by Antmicro. 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 + +module t(/*AUTOARG*/ + // inputs + clk +); + input clk; + bit [31:0] outA; + bit [31:0] outB; + + subA subA(.out(outA)); + subB subB(.out(outB)); + + always @(posedge clk) begin + if (outA == `VALUE_A && outB == `VALUE_B) begin + $write("*-* All Finished *-*\n"); + $finish; + end + else begin + $write("Mismatch\n"); + $stop; + end + end +endmodule diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import.vh b/test_regress/t/t_hier_block_import/t_hier_block_import.vh new file mode 100644 index 000000000..d0cc5e74d --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import.vh @@ -0,0 +1,13 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 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 + +// No include guards to validate if included once. + +parameter param_t pt = '{ + PARAM_VALUE: `VALUE_A +} diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import_args.f b/test_regress/t/t_hier_block_import/t_hier_block_import_args.f new file mode 100644 index 000000000..11c92e3ab --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import_args.f @@ -0,0 +1,11 @@ +# Copyright 2024 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 + +--stats +--hierarchical +$TEST_ROOT/t_hier_block_import_subA.v +-v $TEST_ROOT/t_hier_block_import_subB.v +$TEST_ROOT/t_hier_block_import_subsub.v diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import_def.vh b/test_regress/t/t_hier_block_import/t_hier_block_import_def.vh new file mode 100644 index 000000000..e2877ac06 --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import_def.vh @@ -0,0 +1,16 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 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 + +// No include guards to validate if included once. + +`define VALUE_A 32'h12345678 +`define VALUE_B 32'h87654321 + +typedef struct packed { + bit [31:0] PARAM_VALUE; +} param_t; diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import_subA.v b/test_regress/t/t_hier_block_import/t_hier_block_import_subA.v new file mode 100644 index 000000000..770b57f67 --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import_subA.v @@ -0,0 +1,11 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 by Antmicro. 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 + +module subA (output bit [31:0] out); /*verilator hier_block*/ + subsub subsub(.out(out)); +endmodule diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import_subB.v b/test_regress/t/t_hier_block_import/t_hier_block_import_subB.v new file mode 100644 index 000000000..3fb930bd8 --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import_subB.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 by Antmicro. 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 + +// Note: no hier_block pragma here to validate partial hier_block design +module subB (output bit [31:0] out); + assign out = `VALUE_B; +endmodule diff --git a/test_regress/t/t_hier_block_import/t_hier_block_import_subsub.v b/test_regress/t/t_hier_block_import/t_hier_block_import_subsub.v new file mode 100644 index 000000000..13d6d4014 --- /dev/null +++ b/test_regress/t/t_hier_block_import/t_hier_block_import_subsub.v @@ -0,0 +1,15 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Copyright 2024 by Antmicro. 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 + +module subsub +#( + `include "t_hier_block_import.vh" +) +(output bit [31:0] out); /*verilator hier_block*/ + assign out = pt.PARAM_VALUE; +endmodule diff --git a/test_regress/t/t_hier_block_import_cmake.py b/test_regress/t/t_hier_block_import_cmake.py new file mode 100755 index 000000000..866eb3ff7 --- /dev/null +++ b/test_regress/t/t_hier_block_import_cmake.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt_all') +# CMake build executes from a different directory than the Make one. +test.top_filename = os.path.abspath("t/t_hier_block_import.v") + +# stats will be deleted but generation will be skipped if libs of hierarchical blocks exist. +test.clean_objs() + +test.setenv('TEST_ROOT', test.t_dir + "/t_hier_block_import") + +test.compile(verilator_make_cmake=True, + verilator_make_gmake=False, + verilator_flags2=[ + '$TEST_ROOT/t_hier_block_import_def.vh', + '-f $TEST_ROOT/t_hier_block_import_args.f', '-I$TEST_ROOT' + ], + threads=(6 if test.vltmt else 1)) + +test.execute() + +test.file_grep(test.obj_dir + "/VsubA/subA.sv", r'^module\s+(\S+)\s+', "subA") +test.file_grep(test.stats, r'HierBlock,\s+Hierarchical blocks\s+(\d+)', 2) + +test.passes() From 54ef9ad31c88dd31309a3fe1d578b93c39778ba6 Mon Sep 17 00:00:00 2001 From: Yilou Wang Date: Thu, 12 Dec 2024 17:31:54 +0100 Subject: [PATCH 144/171] Support associative array basic constrained randomization (#5658) (#5670) --- include/verilated_random.cpp | 6 +- include/verilated_random.h | 227 ++++++++++-------- src/V3AstNodeExpr.h | 1 + src/V3Randomize.cpp | 42 +++- test_regress/t/t_constraint_assoc_arr_bad.out | 9 + test_regress/t/t_constraint_assoc_arr_bad.py | 16 ++ test_regress/t/t_constraint_assoc_arr_bad.v | 38 +++ ...nts.py => t_constraint_assoc_arr_basic.py} | 0 test_regress/t/t_constraint_assoc_arr_basic.v | 180 ++++++++++++++ test_regress/t/t_constraint_unpacked_array.py | 21 ++ ...raints.v => t_constraint_unpacked_array.v} | 2 +- 11 files changed, 441 insertions(+), 101 deletions(-) create mode 100644 test_regress/t/t_constraint_assoc_arr_bad.out create mode 100755 test_regress/t/t_constraint_assoc_arr_bad.py create mode 100644 test_regress/t/t_constraint_assoc_arr_bad.v rename test_regress/t/{t_randomize_array_constraints.py => t_constraint_assoc_arr_basic.py} (100%) create mode 100644 test_regress/t/t_constraint_assoc_arr_basic.v create mode 100755 test_regress/t/t_constraint_unpacked_array.py rename test_regress/t/{t_randomize_array_constraints.v => t_constraint_unpacked_array.v} (99%) diff --git a/include/verilated_random.cpp b/include/verilated_random.cpp index 13c6a058a..3dc3b24b0 100644 --- a/include/verilated_random.cpp +++ b/include/verilated_random.cpp @@ -464,10 +464,10 @@ bool VlRandomizer::parseSolution(std::iostream& f) { const size_t start = hex_index.find_first_not_of(" "); if (start == std::string::npos || hex_index.substr(start, 2) != "#x") { VL_FATAL_MT(__FILE__, __LINE__, "randomize", - "Error: hex_index contains invalid format"); + "hex_index contains invalid format"); continue; } - const int index = std::stoi(hex_index.substr(start + 2), nullptr, 16); + const long long index = std::stoll(hex_index.substr(start + 2), nullptr, 16); oss << "[" << index << "]"; } const std::string indexed_name = oss.str(); @@ -481,7 +481,7 @@ bool VlRandomizer::parseSolution(std::iostream& f) { idx = ss.str(); } else { VL_FATAL_MT(__FILE__, __LINE__, "randomize", - "Error: indexed_name not found in m_arr_vars"); + "indexed_name not found in m_arr_vars"); } } varr.set(idx, value); diff --git a/include/verilated_random.h b/include/verilated_random.h index 4dd840149..90d92aa9e 100644 --- a/include/verilated_random.h +++ b/include/verilated_random.h @@ -29,6 +29,7 @@ #include #include + //============================================================================= // VlRandomExpr and subclasses represent expressions for the constraint solver. class ArrayInfo final { @@ -38,12 +39,15 @@ public: void* const m_datap; // Reference to the array variable data const int m_index; // Flattened (1D) index of the array element const std::vector m_indices; // Multi-dimensional indices of the array element + const std::vector m_idxWidths; // Multi-dimensional indices' bit widths - ArrayInfo(const std::string& name, void* datap, int index, const std::vector& indices) + ArrayInfo(const std::string& name, void* datap, int index, const std::vector& indices, + const std::vector& idxWidths) : m_name(name) , m_datap(datap) , m_index(index) - , m_indices(indices) {} + , m_indices(indices) + , m_idxWidths(idxWidths) {} }; using ArrayInfoMap = std::map>; @@ -90,25 +94,30 @@ public: return count; } }; - template -class VlRandomQueueVar final : public VlRandomVar { +class VlRandomArrayVarTemplate final : public VlRandomVar { public: - VlRandomQueueVar(const char* name, int width, void* datap, int dimension, - std::uint32_t randModeIdx) + VlRandomArrayVarTemplate(const char* name, int width, void* datap, int dimension, + std::uint32_t randModeIdx) : VlRandomVar{name, width, datap, dimension, randModeIdx} {} void* datap(int idx) const override { const std::string indexed_name = name() + std::to_string(idx); const auto it = m_arrVarsRefp->find(indexed_name); - if (it != m_arrVarsRefp->end()) return it->second->m_datap; - return &static_cast(VlRandomVar::datap(idx))->atWrite(idx); + if (it != m_arrVarsRefp->end()) { + return it->second->m_datap; + } else { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", "indexed_name not found in m_arr_vars"); + return nullptr; + } } - void emitSelect(std::ostream& s, const std::vector& indices) const { + void emitSelect(std::ostream& s, const std::vector& indices, + const std::vector& idxWidths) const { for (size_t idx = 0; idx < indices.size(); ++idx) s << "(select "; s << name(); for (size_t idx = 0; idx < indices.size(); ++idx) { s << " #x"; - for (int j = 28; j >= 0; j -= 4) { + const size_t bit_width = idxWidths[idx]; + for (int j = bit_width - 4; j >= 0; j -= 4) { s << "0123456789abcdef"[(indices[idx] >> j) & 0xf]; } s << ")"; @@ -121,15 +130,28 @@ public: const auto it = m_arrVarsRefp->find(indexed_name); if (it != m_arrVarsRefp->end()) { const std::vector& indices = it->second->m_indices; - emitSelect(s, indices); + const std::vector& idxWidths = it->second->m_idxWidths; + emitSelect(s, indices, idxWidths); + } else { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", + "indexed_name not found in m_arr_vars"); } } } void emitType(std::ostream& s) const override { - if (dimension() > 0) { - for (int i = 0; i < dimension(); ++i) s << "(Array (_ BitVec 32) "; - s << "(_ BitVec " << width() << ")"; - for (int i = 0; i < dimension(); ++i) s << ")"; + const std::string indexed_name = name() + std::to_string(0); + const auto it = m_arrVarsRefp->find(indexed_name); + if (it != m_arrVarsRefp->end()) { + const std::vector& idxWidths = it->second->m_idxWidths; + if (dimension() > 0) { + for (int i = 0; i < dimension(); ++i) { + s << "(Array (_ BitVec " << idxWidths[i] << ") "; + } + s << "(_ BitVec " << width() << ")"; + for (int i = 0; i < dimension(); ++i) { s << ")"; } + } + } else { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", "indexed_name not found in m_arr_vars"); } } int totalWidth() const override { @@ -144,66 +166,10 @@ public: const auto it = m_arrVarsRefp->find(indexed_name); if (it != m_arrVarsRefp->end()) { const std::vector& indices = it->second->m_indices; - emitSelect(s, indices); - } - s << ')'; - } -}; - -template -class VlRandomArrayVar final : public VlRandomVar { -public: - VlRandomArrayVar(const char* name, int width, void* datap, int dimension, - std::uint32_t randModeIdx) - : VlRandomVar{name, width, datap, dimension, randModeIdx} {} - void* datap(int idx) const override { - const std::string indexed_name = name() + std::to_string(idx); - const auto it = m_arrVarsRefp->find(indexed_name); - if (it != m_arrVarsRefp->end()) return it->second->m_datap; - return &static_cast(VlRandomVar::datap(idx))->operator[](idx); - } - void emitSelect(std::ostream& s, const std::vector& indices) const { - for (size_t idx = 0; idx < indices.size(); ++idx) s << "(select "; - s << name(); - for (size_t idx = 0; idx < indices.size(); ++idx) { - s << " #x"; - for (int j = 28; j >= 0; j -= 4) { - s << "0123456789abcdef"[(indices[idx] >> j) & 0xf]; - } - s << ")"; - } - } - void emitGetValue(std::ostream& s) const override { - const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); - for (int i = 0; i < elementCounts; i++) { - const std::string indexed_name = name() + std::to_string(i); - const auto it = m_arrVarsRefp->find(indexed_name); - if (it != m_arrVarsRefp->end()) { - const std::vector& indices = it->second->m_indices; - emitSelect(s, indices); - } - } - } - void emitType(std::ostream& s) const override { - if (dimension() > 0) { - for (int i = 0; i < dimension(); ++i) s << "(Array (_ BitVec 32) "; - s << "(_ BitVec " << width() << ")"; - for (int i = 0; i < dimension(); ++i) s << ")"; - } - } - int totalWidth() const override { - const int elementCounts = countMatchingElements(*m_arrVarsRefp, name()); - return width() * elementCounts; - } - void emitExtract(std::ostream& s, int i) const override { - const int j = i / width(); - i = i % width(); - s << " ((_ extract " << i << ' ' << i << ')'; - const std::string indexed_name = name() + std::to_string(j); - const auto it = m_arrVarsRefp->find(indexed_name); - if (it != m_arrVarsRefp->end()) { - const std::vector& indices = it->second->m_indices; - emitSelect(s, indices); + const std::vector& idxWidths = it->second->m_idxWidths; + emitSelect(s, indices, idxWidths); + } else { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", "indexed_name not found in m_arr_vars"); } s << ')'; } @@ -217,6 +183,7 @@ class VlRandomizer final { std::map> m_vars; // Solver-dependent // variables ArrayInfoMap m_arr_vars; // Tracks each element in array structures for iteration + std::map seen_values; // Record String Index to avoid conflicts const VlQueue* m_randmode; // rand_mode state; // PRIVATE METHODS @@ -231,6 +198,47 @@ public: // METHODS // Finds the next solution satisfying the constraints bool next(VlRNG& rngr); + + template + typename std::enable_if::value>::type + process_key(const T_Key& key, std::string& indexed_name, size_t& integral_index, + const std::string& base_name, size_t& idx_width) { + integral_index = static_cast(key); + indexed_name = base_name + "[" + std::to_string(integral_index) + "]"; + idx_width = sizeof(T_Key) * 8; + } + template + typename std::enable_if::value>::type + process_key(const T_Key& key, std::string& indexed_name, size_t& integral_index, + const std::string& base_name, size_t& idx_width) { + integral_index = string_to_integral(key); + indexed_name = base_name + "[" + std::to_string(integral_index) + "]"; + idx_width = 64; // 64-bit mask + } + template + typename std::enable_if::value + && !std::is_same::value>::type + process_key(const T_Key& key, std::string& indexed_name, size_t& integral_index, + const std::string& base_name, size_t& idx_width) { + VL_FATAL_MT(__FILE__, __LINE__, "randomize", + "Unsupported: Only integral and string index of associative array is " + "supported currently."); + } + + uint64_t string_to_integral(const std::string& str) { + uint64_t result = 0; + for (char c : str) { result = (result << 8) | static_cast(c); } + +#ifdef VL_DEBUG + if (seen_values.count(result) > 0 && seen_values[result] != str) + VL_WARN_MT(__FILE__, __LINE__, "randomize", + "Conflict detected: Different strings mapped to the same 64-bit index."); + seen_values[result] = str; +#endif + + return result; + } + template void write_var(T& var, int width, const char* name, int dimension, std::uint32_t randmodeIdx = std::numeric_limits::max()) { @@ -243,25 +251,38 @@ public: void write_var(VlQueue& var, int width, const char* name, int dimension, std::uint32_t randmodeIdx = std::numeric_limits::max()) { if (m_vars.find(name) != m_vars.end()) return; - m_vars[name] = std::make_shared>>( + m_vars[name] = std::make_shared>>( name, width, &var, dimension, randmodeIdx); if (dimension > 0) { idx = 0; - record_arr_table(var, name, dimension, {}); + record_arr_table(var, name, dimension, {}, {}); } } template void write_var(VlUnpacked& var, int width, const char* name, int dimension, std::uint32_t randmodeIdx = std::numeric_limits::max()) { if (m_vars.find(name) != m_vars.end()) return; - m_vars[name] = std::make_shared>>( + m_vars[name] = std::make_shared>>( name, width, &var, dimension, randmodeIdx); if (dimension > 0) { idx = 0; - record_arr_table(var, name, dimension, {}); + record_arr_table(var, name, dimension, {}, {}); } } - int idx = 0; + template + void write_var(VlAssocArray& var, int width, const char* name, int dimension, + std::uint32_t randmodeIdx = std::numeric_limits::max()) { + if (m_vars.find(name) != m_vars.end()) return; + m_vars[name] + = std::make_shared>>( + name, width, &var, dimension, randmodeIdx); + if (dimension > 0) { + idx = 0; + record_arr_table(var, name, dimension, {}, {}); + } + } + + int idx; std::string generateKey(const std::string& name, int idx) { if (!name.empty() && name[0] == '\\') { const size_t space_pos = name.find(' '); @@ -272,45 +293,61 @@ public: return (bracket_pos != std::string::npos ? name.substr(0, bracket_pos) : name) + std::to_string(idx); } + template void record_arr_table(T& var, const std::string name, int dimension, - std::vector indices) { + std::vector indices, std::vector idxWidths) { const std::string key = generateKey(name, idx); - m_arr_vars[key] = std::make_shared(name, &var, idx, indices); - idx += 1; + m_arr_vars[key] = std::make_shared(name, &var, idx, indices, idxWidths); + ++idx; } template void record_arr_table(VlQueue& var, const std::string name, int dimension, - std::vector indices) { + std::vector indices, std::vector idxWidths) { if ((dimension > 0) && (var.size() != 0)) { + idxWidths.push_back(32); for (size_t i = 0; i < var.size(); ++i) { const std::string indexed_name = name + "[" + std::to_string(i) + "]"; indices.push_back(i); - record_arr_table(var.atWrite(i), indexed_name, dimension - 1, indices); + record_arr_table(var.atWrite(i), indexed_name, dimension - 1, indices, idxWidths); indices.pop_back(); } - } else { - const std::string key = generateKey(name, idx); - m_arr_vars[key] = std::make_shared(name, &var, idx, indices); - ++idx; } } template void record_arr_table(VlUnpacked& var, const std::string name, int dimension, - std::vector indices) { + std::vector indices, std::vector idxWidths) { if ((dimension > 0) && (N_Depth != 0)) { + idxWidths.push_back(32); for (size_t i = 0; i < N_Depth; ++i) { const std::string indexed_name = name + "[" + std::to_string(i) + "]"; indices.push_back(i); - record_arr_table(var.operator[](i), indexed_name, dimension - 1, indices); + record_arr_table(var.operator[](i), indexed_name, dimension - 1, indices, + idxWidths); indices.pop_back(); } - } else { - const std::string key = generateKey(name, idx); - m_arr_vars[key] = std::make_shared(name, &var, idx, indices); - idx += 1; } } + template + void record_arr_table(VlAssocArray& var, const std::string name, int dimension, + std::vector indices, std::vector idxWidths) { + if ((dimension > 0) && (var.size() != 0)) { + for (auto it = var.begin(); it != var.end(); ++it) { + const T_Key& key = it->first; + const T_Value& value = it->second; + std::string indexed_name; + size_t integral_index; + size_t idx_width; + process_key(key, indexed_name, integral_index, name, idx_width); + idxWidths.push_back(idx_width); + indices.push_back(integral_index); + record_arr_table(var.at(key), indexed_name, dimension - 1, indices, idxWidths); + idxWidths.pop_back(); + indices.pop_back(); + } + } + } + void hard(std::string&& constraint); void clear(); void set_randmode(const VlQueue& randmode) { m_randmode = &randmode; } diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 5237268e6..a97853dd2 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4191,6 +4191,7 @@ public: } string emitVerilog() override { return "%k(%l%f[%r])"; } string emitC() override { return "%li%k[%ri]"; } + string emitSMT() const override { return "(select %l %r)"; } bool cleanOut() const override { return true; } bool cleanLhs() const override { return false; } bool cleanRhs() const override { return true; } diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index b6507c960..4067cff6b 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -641,7 +641,7 @@ class ConstraintExprVisitor final : public VNVisitor { "write_var"}; uint32_t dimension = 0; if (VN_IS(varp->dtypep(), UnpackArrayDType) || VN_IS(varp->dtypep(), DynArrayDType) - || VN_IS(varp->dtypep(), QueueDType)) { + || VN_IS(varp->dtypep(), QueueDType) || VN_IS(varp->dtypep(), AssocArrayDType)) { const std::pair dims = varp->dtypep()->dimensions(/*includeBasic=*/true); const uint32_t unpackedDimensions = dims.second; @@ -656,7 +656,7 @@ class ConstraintExprVisitor final : public VNVisitor { size_t width = varp->width(); AstNodeDType* tmpDtypep = varp->dtypep(); while (VN_IS(tmpDtypep, UnpackArrayDType) || VN_IS(tmpDtypep, DynArrayDType) - || VN_IS(tmpDtypep, QueueDType)) + || VN_IS(tmpDtypep, QueueDType) || VN_IS(tmpDtypep, AssocArrayDType)) tmpDtypep = tmpDtypep->subDTypep(); width = tmpDtypep->width(); methodp->addPinsp( @@ -724,6 +724,44 @@ class ConstraintExprVisitor final : public VNVisitor { editSMT(nodep, nodep->fromp(), lsbp, msbp); } + void visit(AstAssocSel* nodep) override { + if (editFormat(nodep)) return; + FileLine* const fl = nodep->fileline(); + if (VN_IS(nodep->bitp(), CvtPackString)) { + // Extract and truncate the string index to fit within 64 bits + AstCvtPackString* const stringp = VN_AS(nodep->bitp(), CvtPackString); + VNRelinker handle; + AstNodeExpr* const strIdxp = new AstSFormatF{ + fl, "#x%16x", false, + new AstAnd{fl, stringp->lhsp()->unlinkFrBack(&handle), + new AstConst(fl, AstConst::Unsized64{}, 0xFFFFFFFFFFFFFFFF)}}; + handle.relink(strIdxp); + editSMT(nodep, nodep->fromp(), strIdxp); + } else { + VNRelinker handle; + const int actual_width = nodep->bitp()->width(); + std::string fmt; + // Normalize to standard bit width + if (actual_width <= 8) { + fmt = "#x%2x"; + } else if (actual_width <= 16) { + fmt = "#x%4x"; + } else if (actual_width <= 32) { + fmt = "#x%8x"; + } else if (actual_width <= 64) { + fmt = "#x%16x"; + } else { + nodep->v3warn(CONSTRAINTIGN, + "Unsupported: Associative array index " + "widths of more than 64 bits during constraint randomization."); + return; + } + AstNodeExpr* const idxp + = new AstSFormatF{fl, fmt, false, nodep->bitp()->unlinkFrBack(&handle)}; + handle.relink(idxp); + editSMT(nodep, nodep->fromp(), idxp); + } + } void visit(AstArraySel* nodep) override { if (editFormat(nodep)) return; FileLine* const fl = nodep->fileline(); diff --git a/test_regress/t/t_constraint_assoc_arr_bad.out b/test_regress/t/t_constraint_assoc_arr_bad.out new file mode 100644 index 000000000..a048591fc --- /dev/null +++ b/test_regress/t/t_constraint_assoc_arr_bad.out @@ -0,0 +1,9 @@ +%Warning-CONSTRAINTIGN: t/t_constraint_assoc_arr_bad.v:14:22: Unsupported: Associative array index widths of more than 64 bits during constraint randomization. + 14 | bit_index_arr[79'd66] == 65; + | ^ + ... For warning description see https://verilator.org/warn/CONSTRAINTIGN?v=latest + ... Use "/* verilator lint_off CONSTRAINTIGN */" and lint_on around source to disable this message. +%Warning-CONSTRAINTIGN: t/t_constraint_assoc_arr_bad.v:15:24: Unsupported: Associative array index widths of more than 64 bits during constraint randomization. + 15 | logic_index_arr[65'd3] == 70; + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_constraint_assoc_arr_bad.py b/test_regress/t/t_constraint_assoc_arr_bad.py new file mode 100755 index 000000000..efe8cc01c --- /dev/null +++ b/test_regress/t/t_constraint_assoc_arr_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_constraint_assoc_arr_bad.v b/test_regress/t/t_constraint_assoc_arr_bad.v new file mode 100644 index 000000000..2050f2643 --- /dev/null +++ b/test_regress/t/t_constraint_assoc_arr_bad.v @@ -0,0 +1,38 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by PlanV GmbH. +// SPDX-License-Identifier: CC0-1.0 + + +class AssocArrayWarningTest; + + rand int bit_index_arr [bit[78:0]]; + rand int logic_index_arr [logic[64:0]]; + + constraint c { + bit_index_arr[79'd66] == 65; + logic_index_arr[65'd3] == 70; + } + function new(); + bit_index_arr = '{79'd66:0}; + logic_index_arr = '{65'd3:0}; + endfunction + +endclass + +module t_constraint_assoc_arr_bad; + + AssocArrayWarningTest test_obj; + + initial begin + test_obj = new(); + repeat(2) begin + int success; + success = test_obj.randomize(); + if (success != 1) $stop; + end + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_randomize_array_constraints.py b/test_regress/t/t_constraint_assoc_arr_basic.py similarity index 100% rename from test_regress/t/t_randomize_array_constraints.py rename to test_regress/t/t_constraint_assoc_arr_basic.py diff --git a/test_regress/t/t_constraint_assoc_arr_basic.v b/test_regress/t/t_constraint_assoc_arr_basic.v new file mode 100644 index 000000000..105cdb96a --- /dev/null +++ b/test_regress/t/t_constraint_assoc_arr_basic.v @@ -0,0 +1,180 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by PlanV GmbH. +// SPDX-License-Identifier: CC0-1.0 + +class constrained_associative_array_basic; + + rand int int_index_arr [int]; + rand int string_index_arr [string]; + /* verilator lint_off SIDEEFFECT */ + // Constraints for both arrays + constraint int_index_constraints { + foreach (int_index_arr[i]) int_index_arr[i] inside {10, 20, 30, 40, 50}; + } + constraint string_index_constraints { + string_index_arr["Alice"] == 35; + string_index_arr["Bob"] inside {50, 60}; + string_index_arr["Charlie"] > 25; + } + + // Constructor to initialize arrays + function new(); + int_index_arr = '{1: 0, 8: 0, 7: 0}; + string_index_arr = '{"Alice": 25, "Bob": 50, "Charlie": 45}; + endfunction + + // Function to check and display the arrays + function void self_check(); + foreach (int_index_arr[i]) begin + if (!(int_index_arr[i] inside {10, 20, 30, 40, 50})) $stop; + end + foreach (string_index_arr[name]) begin + if ((name == "Alice" && string_index_arr[name] != 35) || + (name == "Bob" && !(string_index_arr[name] inside {50, 60})) || + (name == "Charlie" && string_index_arr[name] <= 25)) $stop; + end + endfunction + +endclass + +class constrained_1d_associative_array; + + rand int string_index_arr [string]; + rand int int_index_arr [int]; + rand int shortint_index_arr [shortint]; + rand int longint_index_arr[longint]; + rand int byte_index_arr [byte]; + rand int bit_index_arr [bit[5:0]]; + rand int logic_index_arr [logic[3:0]]; + rand int bit_index_arr_1 [bit[55:0]]; + + // Constraints + constraint associative_array_constraints { + string_index_arr["key1"] == 100; + string_index_arr["key2"] inside {200, 300, 400}; + int_index_arr[40000] + int_index_arr[2000000000] == 2; + shortint_index_arr[2000] == 200; + longint_index_arr[64'd4000000000] == 300; + byte_index_arr[8'd255] == 50; + bit_index_arr[6'd30] - bit_index_arr_1[56'd66] == 3; + logic_index_arr[4'b0011] == 70; + } + + function new(); + string_index_arr = '{"key1":0, "key2":0}; + int_index_arr = '{40000:0, 2000000000:0}; + shortint_index_arr = '{2000:0}; + longint_index_arr = '{64'd4000000000:0}; + byte_index_arr = '{8'd255:0}; + bit_index_arr = '{6'd30:0}; + bit_index_arr_1 = '{56'd66:0}; + logic_index_arr = '{4'd3:0}; + endfunction + + function void self_check(); + if (string_index_arr["key1"] != 100) $stop; + if (!(string_index_arr["key2"] inside {200, 300, 400})) $stop; + if ((int_index_arr[40000] + int_index_arr[2000000000]) != 2) $stop; + if (shortint_index_arr[2000] != 200) $stop; + if (longint_index_arr[64'd4000000000] != 300) $stop; + if (byte_index_arr[8'd255] != 50) $stop; + if (bit_index_arr[6'd30] - bit_index_arr_1[56'd66] != 3) $stop; + if (logic_index_arr[4'd3] != 70) $stop; + endfunction + + function void debug_display(); + $display("string_index_arr[\"key1\"] = %0d", string_index_arr["key1"]); + $display("string_index_arr[\"key2\"] = %0d", string_index_arr["key2"]); + $display("int_index_arr[40000] = %0d", int_index_arr[40000]); + $display("int_index_arr[2000000000] = %0d", int_index_arr[2000000000]); + $display("shortint_index_arr[2000] = %0d", shortint_index_arr[2000]); + $display("longint_index_arr[4000000000] = %0d", longint_index_arr[64'd4000000000]); + $display("byte_index_arr[255] = %0d", byte_index_arr[8'd255]); + $display("bit_index_arr[30] = %0d", bit_index_arr[6'd30]); + $display("bit_index_arr_1[66] = %0d", bit_index_arr_1[56'd66]); + $display("logic_index_arr[3] = %0d", logic_index_arr[4'd3]); + endfunction + +endclass + +class constrained_2d_associative_array; + + rand int string_int_index_arr [string][int]; + rand int int_bit_index_arr [int][bit[5:0]]; + rand int string_bit_index_arr [string][bit[7:0]]; + rand int unpacked_assoc_array_2d [string][2]; + + // Constraints + constraint associative_array_constraints { + string_int_index_arr["key1"][2000] == 100; + string_int_index_arr["key2"][3000] inside {200, 300, 400}; + int_bit_index_arr[40000][6'd30] == 60; + int_bit_index_arr[50000][6'd40] inside {100, 200}; + string_bit_index_arr["key3"][8'd100] == 150; + string_bit_index_arr["key4"][8'd200] inside {250, 350}; + unpacked_assoc_array_2d["key5"][0] == 7; + } + + function new(); + string_int_index_arr = '{"key1":'{2000:0}, "key2":'{3000:0}}; + int_bit_index_arr = '{40000:'{6'd30:0}, 50000:'{6'd40:0}}; + string_bit_index_arr = '{"key3":'{8'd100:0}, "key4":'{8'd200:0}}; + unpacked_assoc_array_2d["key5"][0] = 0; + unpacked_assoc_array_2d["key5"][1] = 0; + endfunction + + function void self_check(); + if (string_int_index_arr["key1"][2000] != 100) $stop; + if (!(string_int_index_arr["key2"][3000] inside {200, 300, 400})) $stop; + if (int_bit_index_arr[40000][6'd30] != 60) $stop; + if (!(int_bit_index_arr[50000][6'd40] inside {100, 200})) $stop; + if (string_bit_index_arr["key3"][8'd100] != 150) $stop; + if (!(string_bit_index_arr["key4"][8'd200] inside {250, 350})) $stop; + if (unpacked_assoc_array_2d["key5"][0] != 7) $stop; + endfunction + + function void debug_display(); + $display("string_int_index_arr[\"key1\"][2000] = %0d", string_int_index_arr["key1"][2000]); + $display("string_int_index_arr[\"key2\"][3000] = %0d", string_int_index_arr["key2"][3000]); + $display("int_bit_index_arr[40000][30] = %0d", int_bit_index_arr[40000][6'd30]); + $display("int_bit_index_arr[50000][40] = %0d", int_bit_index_arr[50000][6'd40]); + $display("string_bit_index_arr[\"key3\"][100] = %0d", string_bit_index_arr["key3"][8'd100]); + $display("string_bit_index_arr[\"key4\"][200] = %0d", string_bit_index_arr["key4"][8'd200]); + $display("unpacked_assoc_array_2d[\"key5\"][0] = %0d", unpacked_assoc_array_2d["key5"][0]); + endfunction + /* verilator lint_off SIDEEFFECT */ +endclass + +module t_constraint_assoc_arr_basic; + + constrained_associative_array_basic my_array; + constrained_1d_associative_array my_1d_array; + constrained_2d_associative_array my_2d_array; + int success; + + initial begin + my_array = new(); + success = my_array.randomize(); + if (success == 0) $stop; + my_array.self_check(); + + my_1d_array = new(); + success = my_1d_array.randomize(); + if (success == 0) $stop; + my_1d_array.self_check(); + + my_1d_array = new(); + success = my_1d_array.randomize(); + if (success == 0) $stop; + my_1d_array.self_check(); + + // my_1d_array.debug_display(); + // my_2d_array.debug_display(); + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule diff --git a/test_regress/t/t_constraint_unpacked_array.py b/test_regress/t/t_constraint_unpacked_array.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_constraint_unpacked_array.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_array_constraints.v b/test_regress/t/t_constraint_unpacked_array.v similarity index 99% rename from test_regress/t/t_randomize_array_constraints.v rename to test_regress/t/t_constraint_unpacked_array.v index f56cab447..1d7ecfbc6 100755 --- a/test_regress/t/t_randomize_array_constraints.v +++ b/test_regress/t/t_constraint_unpacked_array.v @@ -125,7 +125,7 @@ class con_rand_3d_array_test; endclass -module t_randomize_array_constraints; +module t_constraint_unpacked_array; con_rand_1d_array_test rand_test_1; con_rand_2d_array_test rand_test_2; con_rand_3d_array_test rand_test_3; From a8e06874bd1b98989b59d7cf9a9ac0d5a019a7d2 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Fri, 13 Dec 2024 15:32:47 +0100 Subject: [PATCH 145/171] Fix `randomize..with` of parameterized classes (#5676) Broke in 7a04a5b --- src/V3LinkDot.cpp | 9 ++++- test_regress/t/t_randomize_param_with.py | 21 +++++++++++ test_regress/t/t_randomize_param_with.v | 48 ++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_randomize_param_with.py create mode 100644 test_regress/t/t_randomize_param_with.v diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index d0cdc3903..539a83d74 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3916,9 +3916,14 @@ class LinkDotResolveVisitor final : public VNVisitor { LINKDOT_VISIT_START(); UINFO(5, indent() << "visit " << nodep << endl); checkNoDot(nodep); + VL_RESTORER(m_curSymp); VL_RESTORER(m_inWith); - m_inWith = true; - symIterateChildren(nodep, m_statep->getNodeSym(nodep)); + { + m_ds.m_dotSymp = m_curSymp = m_statep->getNodeSym(nodep); + m_inWith = true; + iterateChildren(nodep); + } + m_ds.m_dotSymp = VL_RESTORER_PREV(m_curSymp); } void visit(AstLambdaArgRef* nodep) override { LINKDOT_VISIT_START(); diff --git a/test_regress/t/t_randomize_param_with.py b/test_regress/t/t_randomize_param_with.py new file mode 100755 index 000000000..a2b131082 --- /dev/null +++ b/test_regress/t/t_randomize_param_with.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +if not test.have_solver: + test.skip("No constraint solver installed") + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_randomize_param_with.v b/test_regress/t/t_randomize_param_with.v new file mode 100644 index 000000000..3b7039436 --- /dev/null +++ b/test_regress/t/t_randomize_param_with.v @@ -0,0 +1,48 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro Ltd. +// SPDX-License-Identifier: CC0-1.0 + +`define check_rand(cl, field, constr, cond) \ +begin \ + longint prev_result; \ + int ok = 0; \ + if (!bit'(cl.randomize() with { constr; })) $stop; \ + prev_result = longint'(field); \ + if (!(cond)) $stop; \ + repeat(9) begin \ + longint result; \ + if (!bit'(cl.randomize() with { constr; })) $stop; \ + result = longint'(field); \ + if (!(cond)) $stop; \ + if (result != prev_result) ok = 1; \ + prev_result = result; \ + end \ + if (ok != 1) $stop; \ +end + +class Cls #(int LIMIT = 3); + rand int x; + int y = -100; + constraint x_limit { x <= LIMIT; }; +endclass + +module t; + initial begin + Cls#() cd = new; + Cls#(5) c5 = new; + + `check_rand(cd, cd.x, x > 0, cd.x > 0 && cd.x <= 3); + `check_rand(cd, cd.x, x > y, cd.x > -100 && cd.x <= 3); + if (cd.randomize() with {x > 3;} == 1) $stop; + + `check_rand(c5, c5.x, x > 0, c5.x > 0 && c5.x <= 5); + `check_rand(c5, c5.x, x > y, c5.x > -100 && c5.x <= 5); + if (c5.randomize() with {x >= 5;} == 0) $stop; + if (c5.x != 5) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 41a038b79b4069b7262b9cbd96b925463ccd5ab5 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Fri, 13 Dec 2024 12:00:49 -0500 Subject: [PATCH 146/171] Fix interface bracketed array parameter access (#5678) (#5677) --- src/V3Param.cpp | 29 ++++++++------ .../t/t_interface_array_parameter_access.py | 18 +++++++++ .../t/t_interface_array_parameter_access.v | 39 +++++++++++++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_interface_array_parameter_access.py create mode 100644 test_regress/t/t_interface_array_parameter_access.v diff --git a/src/V3Param.cpp b/src/V3Param.cpp index fd5479feb..0d6a3c6ca 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -1249,18 +1249,25 @@ class ParamVisitor final : public VNVisitor { UINFO(9, "Hit module boundary, done looking for interface" << endl); break; } - if (VN_IS(backp, Var) && VN_AS(backp, Var)->isIfaceRef() - && VN_AS(backp, Var)->childDTypep() - && (VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType) - || (VN_CAST(VN_CAST(backp, Var)->childDTypep(), UnpackArrayDType) - && VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), - IfaceRefDType)))) { - const AstIfaceRefDType* ifacerefp - = VN_CAST(VN_CAST(backp, Var)->childDTypep(), IfaceRefDType); - if (!ifacerefp) { - ifacerefp = VN_CAST(VN_CAST(backp, Var)->childDTypep()->getChildDTypep(), - IfaceRefDType); + if (const AstVar* const varp = VN_CAST(backp, Var)) { + if (!varp->isIfaceRef()) { continue; } + const AstIfaceRefDType* ifacerefp = nullptr; + if (const AstNodeDType* const typep = varp->childDTypep()) { + ifacerefp = VN_CAST(typep, IfaceRefDType); + if (!ifacerefp) { + if (const AstUnpackArrayDType* const unpackp + = VN_CAST(typep, UnpackArrayDType)) { + ifacerefp = VN_CAST(typep->getChildDTypep(), IfaceRefDType); + } + } + if (!ifacerefp) { + if (const AstBracketArrayDType* const unpackp + = VN_CAST(typep, BracketArrayDType)) { + ifacerefp = VN_CAST(typep->subDTypep(), IfaceRefDType); + } + } } + if (!ifacerefp) { continue; } // Interfaces passed in on the port map have ifaces if (const AstIface* const ifacep = ifacerefp->ifacep()) { if (dotted == backp->name()) { diff --git a/test_regress/t/t_interface_array_parameter_access.py b/test_regress/t/t_interface_array_parameter_access.py new file mode 100755 index 000000000..d4f986441 --- /dev/null +++ b/test_regress/t/t_interface_array_parameter_access.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_interface_array_parameter_access.v b/test_regress/t/t_interface_array_parameter_access.v new file mode 100644 index 000000000..33de01a6a --- /dev/null +++ b/test_regress/t/t_interface_array_parameter_access.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Get parameter from array of interfaces +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2024 by Todd Strader +// SPDX-License-Identifier: CC0-1.0 + +interface intf + #(parameter int FOO = 4) + (input wire clk, + input wire rst); + modport modp (input clk, rst); +endinterface + +module sub (intf.modp the_intf_port [4]); + localparam int intf_foo = the_intf_port[0].FOO; + + initial begin + if (intf_foo != 4) $stop; + end +endmodule + +module t ( + clk +); + logic rst; + input clk; + + intf the_intf [4] (.*); + + sub + the_sub ( + .the_intf_port (the_intf) + ); + + always @(posedge clk) begin + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From a23dfdc4ee618ba18412beccee80c276a796c90c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 13 Dec 2024 16:53:59 -0500 Subject: [PATCH 147/171] Fix backward external constraint error, from recent new support. (Thanks sv-tests!) --- src/V3LinkDot.cpp | 2 +- test_regress/t/t_constraint_extern.v | 2 +- test_regress/t/t_constraint_extern_bad.out | 6 +++--- test_regress/t/t_constraint_extern_bad.v | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 539a83d74..55f591aa8 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -3330,7 +3330,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } } if (nodep->isExternProto()) { - if (!m_curSymp->findIdFallback(nodep->name()) && !nodep->isExternExplicit()) { + if (!m_curSymp->findIdFallback(nodep->name()) && nodep->isExternExplicit()) { nodep->v3error("Definition not found for extern " + nodep->prettyNameQ()); } } diff --git a/test_regress/t/t_constraint_extern.v b/test_regress/t/t_constraint_extern.v index 8a7f4602c..ec3888f08 100644 --- a/test_regress/t/t_constraint_extern.v +++ b/test_regress/t/t_constraint_extern.v @@ -11,7 +11,7 @@ class Packet; extern function void f(); constraint cone; extern constraint ctwo; - extern constraint cmissing; // Ok per IEEE 1800-2023 18.5.1 + constraint cmissing; // Ok per IEEE 1800-2023 18.5.1 endclass diff --git a/test_regress/t/t_constraint_extern_bad.out b/test_regress/t/t_constraint_extern_bad.out index da6dfe795..e63efbb03 100644 --- a/test_regress/t/t_constraint_extern_bad.out +++ b/test_regress/t/t_constraint_extern_bad.out @@ -1,6 +1,6 @@ -%Error: t/t_constraint_extern_bad.v:8:15: Definition not found for extern 'missing_bad' - 8 | constraint missing_bad; - | ^~~~~~~~~~~ +%Error: t/t_constraint_extern_bad.v:8:22: Definition not found for extern 'missing_bad' + 8 | extern constraint missing_bad; + | ^~~~~~~~~~~ %Error: t/t_constraint_extern_bad.v:11:20: extern not found that declares 'missing_extern' 11 | constraint Packet::missing_extern { } | ^~~~~~~~~~~~~~ diff --git a/test_regress/t/t_constraint_extern_bad.v b/test_regress/t/t_constraint_extern_bad.v index ebeab9acf..743d9f4b1 100644 --- a/test_regress/t/t_constraint_extern_bad.v +++ b/test_regress/t/t_constraint_extern_bad.v @@ -5,7 +5,7 @@ // SPDX-License-Identifier: CC0-1.0 class Packet; - constraint missing_bad; + extern constraint missing_bad; endclass constraint Packet::missing_extern { } From c2dcca980eedb3f78cd60ff9532a7cf7c1ee93f7 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 13 Dec 2024 17:15:04 -0500 Subject: [PATCH 148/171] Improve to throw UNSUPPORTED instead of syntax error on extend class arguments --- src/verilog.y | 9 +++++++ test_regress/t/t_class_extends_arg.out | 8 ++++++ test_regress/t/t_class_extends_arg.py | 16 ++++++++++++ test_regress/t/t_class_extends_arg.v | 36 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 test_regress/t/t_class_extends_arg.out create mode 100755 test_regress/t/t_class_extends_arg.py create mode 100644 test_regress/t/t_class_extends_arg.v diff --git a/src/verilog.y b/src/verilog.y index ac6b34010..62eaa4815 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -7190,6 +7190,15 @@ classExtendsOne: // IEEE: part of class_declaration class_typeExtImpList { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; $$ = $1; } + | class_typeExtImpList '(' list_of_argumentsE ')' + { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; + BBUNSUP($2, "Unsupported: 'extends' with class list_of_arguments"); + $$ = $1; } + // // IEEE-2023: Added: yEXTENDS class_type '(' yDEFAULT ')' + | class_typeExtImpList '(' yDEFAULT ')' + { $$ = new AstClassExtends{$1->fileline(), $1, GRAMMARP->m_inImplements}; + BBUNSUP($2, "Unsupported: 'extends' with 'default'"); + $$ = $1; } ; classImplementsE: // IEEE: part of class_declaration diff --git a/test_regress/t/t_class_extends_arg.out b/test_regress/t/t_class_extends_arg.out new file mode 100644 index 000000000..a1ec3e818 --- /dev/null +++ b/test_regress/t/t_class_extends_arg.out @@ -0,0 +1,8 @@ +%Error-UNSUPPORTED: t/t_class_extends_arg.v:14:25: Unsupported: 'extends' with 'default' + 14 | class Cls1 extends Base1(default); + | ^ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_class_extends_arg.v:18:25: Unsupported: 'extends' with class list_of_arguments + 18 | class Cls5 extends Base1(5); + | ^ +%Error: Exiting due to diff --git a/test_regress/t/t_class_extends_arg.py b/test_regress/t/t_class_extends_arg.py new file mode 100755 index 000000000..30c3d4f77 --- /dev/null +++ b/test_regress/t/t_class_extends_arg.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_class_extends_arg.v b/test_regress/t/t_class_extends_arg.v new file mode 100644 index 000000000..c32818463 --- /dev/null +++ b/test_regress/t/t_class_extends_arg.v @@ -0,0 +1,36 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2020 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Base1; + int s = 2; + function new(int def = 3); + s = def; + endfunction +endclass + +class Cls1 extends Base1(default); + // Gets new(int def) +endclass + +class Cls5 extends Base1(5); + // Gets new() +endclass + +module t (/*AUTOARG*/); + initial begin + Cls1 c1; + Cls1 c5; + c1 = new(57); + if (c1.s !== 57) $stop; + + c5 = new; + if (c5.s !== 5) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule From 7886204690418113e8cef4a14f49c0c023aab9b9 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 13 Dec 2024 17:58:08 -0500 Subject: [PATCH 149/171] Tests: Add t_class_new_scoped (unsupported) --- test_regress/t/t_class_new_scoped.out | 13 ++++++ test_regress/t/t_class_new_scoped.py | 16 +++++++ test_regress/t/t_class_new_scoped.v | 66 +++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 test_regress/t/t_class_new_scoped.out create mode 100755 test_regress/t/t_class_new_scoped.py create mode 100644 test_regress/t/t_class_new_scoped.v diff --git a/test_regress/t/t_class_new_scoped.out b/test_regress/t/t_class_new_scoped.out new file mode 100644 index 000000000..2e1ac485d --- /dev/null +++ b/test_regress/t/t_class_new_scoped.out @@ -0,0 +1,13 @@ +%Error: t/t_class_new_scoped.v:45:21: syntax error, unexpected new, expecting IDENTIFIER-for-type + 45 | b = ClsNoArg::new; + | ^~~ +%Error: t/t_class_new_scoped.v:50:19: syntax error, unexpected new-then-paren, expecting IDENTIFIER-for-type + 50 | b = ClsArg::new(20, 1); + | ^~~ +%Error: t/t_class_new_scoped.v:55:27: syntax error, unexpected new-then-paren, expecting IDENTIFIER-for-type + 55 | b = ClsParam#(100)::new(33); + | ^~~ +%Error: t/t_class_new_scoped.v:60:27: syntax error, unexpected new-then-paren, expecting IDENTIFIER-for-type + 60 | b = ClsParam#(200)::new(44); + | ^~~ +%Error: Exiting due to diff --git a/test_regress/t/t_class_new_scoped.py b/test_regress/t/t_class_new_scoped.py new file mode 100755 index 000000000..e33e10acf --- /dev/null +++ b/test_regress/t/t_class_new_scoped.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=True, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_class_new_scoped.v b/test_regress/t/t_class_new_scoped.v new file mode 100644 index 000000000..e1c5d1f65 --- /dev/null +++ b/test_regress/t/t_class_new_scoped.v @@ -0,0 +1,66 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`define stop $stop +`define checkd(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=%0d exp=%0d (%s !== %s)\n", `__FILE__,`__LINE__, (gotv), (expv), `"gotv`", `"expv`"); `stop; end while(0); + +class Base; + int imembera = 10; + function new(int i); + imembera = i; + endfunction +endclass + +class ClsNoArg extends Base; + function new(); + super.new(5); + endfunction : new +endclass + +class ClsArg extends Base; + function new(int i, int j); + super.new(i + j); + endfunction +endclass + +class ClsParam #(int ADD = 100) extends Base; + function new(int def = 42); + super.new(def + ADD); + endfunction +endclass + +module t (/*AUTOARG*/); + initial begin + Base b; + ClsNoArg c1; + ClsArg c2; + ClsParam#(100) c3; + ClsParam#(200) c4; + + c1 = new; + `checkd(c1.imembera, 5); + b = ClsNoArg::new; + `checkd(b.imembera, 5); + + c2 = new(20, 1); + `checkd(c2.imembera, 21); + b = ClsArg::new(20, 1); + `checkd(b.imembera, 21); + + c3 = new(33); + `checkd(c3.imembera, 133); + b = ClsParam#(100)::new(33); + `checkd(b.imembera, 133); + + c4 = new(44); + `checkd(c4.imembera, 244); + b = ClsParam#(200)::new(44); + `checkd(b.imembera, 244); + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 80b2fa3583b304bf251901e1eac666256526685c Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 14 Dec 2024 11:47:46 -0500 Subject: [PATCH 150/171] Add error on randc inside dist --- src/V3LinkResolve.cpp | 51 ++++++++++++++++--- src/V3Randomize.cpp | 18 ------- .../t/t_constraint_before_randc_bad.out | 7 +++ ...ad.py => t_constraint_before_randc_bad.py} | 0 ..._bad.v => t_constraint_before_randc_bad.v} | 0 .../t/t_constraint_dist_randc_bad.out | 7 +++ ..._bad.py => t_constraint_dist_randc_bad.py} | 0 test_regress/t/t_constraint_dist_randc_bad.v | 14 +++++ .../t/t_constraint_soft_randc_bad.out | 7 +++ test_regress/t/t_constraint_soft_randc_bad.py | 16 ++++++ ...dc_bad.v => t_constraint_soft_randc_bad.v} | 0 .../t/t_randomize_before_randc_bad.out | 5 -- test_regress/t/t_randomize_soft_randc_bad.out | 5 -- 13 files changed, 95 insertions(+), 35 deletions(-) create mode 100644 test_regress/t/t_constraint_before_randc_bad.out rename test_regress/t/{t_randomize_before_randc_bad.py => t_constraint_before_randc_bad.py} (100%) rename test_regress/t/{t_randomize_before_randc_bad.v => t_constraint_before_randc_bad.v} (100%) create mode 100644 test_regress/t/t_constraint_dist_randc_bad.out rename test_regress/t/{t_randomize_soft_randc_bad.py => t_constraint_dist_randc_bad.py} (100%) create mode 100644 test_regress/t/t_constraint_dist_randc_bad.v create mode 100644 test_regress/t/t_constraint_soft_randc_bad.out create mode 100755 test_regress/t/t_constraint_soft_randc_bad.py rename test_regress/t/{t_randomize_soft_randc_bad.v => t_constraint_soft_randc_bad.v} (100%) delete mode 100644 test_regress/t/t_randomize_before_randc_bad.out delete mode 100644 test_regress/t/t_randomize_soft_randc_bad.out diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index d6d70fef2..ed77ba41e 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -47,6 +47,8 @@ class LinkResolveVisitor final : public VNVisitor { // Below state needs to be preserved between each module call. AstNodeModule* m_modp = nullptr; // Current module AstClass* m_classp = nullptr; // Class we're inside + string m_randcIllegalWhy; // Why randc illegal + AstNode* m_randcIllegalp = nullptr; // Node causing randc illegal AstNodeFTask* m_ftaskp = nullptr; // Function or task we're inside AstNodeCoverOrAssert* m_assertp = nullptr; // Current assertion int m_senitemCvtNum = 0; // Temporary signal counter @@ -82,6 +84,30 @@ class LinkResolveVisitor final : public VNVisitor { } iterateChildren(nodep); } + void visit(AstConstraintBefore* nodep) override { + VL_RESTORER(m_randcIllegalWhy); + VL_RESTORER(m_randcIllegalp); + m_randcIllegalWhy = "'solve before' (IEEE 1800-2023 18.5.9)"; + m_randcIllegalp = nodep; + iterateChildrenConst(nodep); + } + void visit(AstDist* nodep) override { + VL_RESTORER(m_randcIllegalWhy); + VL_RESTORER(m_randcIllegalp); + m_randcIllegalWhy = "'constraint dist' (IEEE 1800-2023 18.5.3)"; + m_randcIllegalp = nodep; + iterateChildrenConst(nodep); + } + void visit(AstConstraintExpr* nodep) override { + VL_RESTORER(m_randcIllegalWhy); + VL_RESTORER(m_randcIllegalp); + if (nodep->isSoft()) { + m_randcIllegalWhy = "'constraint soft' (IEEE 1800-2023 18.5.13.1)"; + m_randcIllegalp = nodep; + } + iterateChildrenConst(nodep); + } + void visit(AstInitialAutomatic* nodep) override { iterateChildren(nodep); // Initial assignments under function/tasks can just be simple @@ -110,13 +136,24 @@ class LinkResolveVisitor final : public VNVisitor { } void visit(AstNodeVarRef* nodep) override { - // VarRef: Resolve its reference - if (nodep->varp()) nodep->varp()->usedParam(true); - // TODO should look for where genvar is valid, but for now catch - // just gross errors of using genvar outside any generate - if (nodep->varp() && nodep->varp()->isGenVar() && !m_underGenFor) { - nodep->v3error("Genvar " << nodep->prettyNameQ() - << " used outside generate for loop (IEEE 1800-2023 27.4)"); + if (nodep->varp()) { // Else due to dead code, might not have var pointer + // VarRef: Resolve its reference + nodep->varp()->usedParam(true); + // TODO should look for where genvar is valid, but for now catch + // just gross errors of using genvar outside any generate + if (nodep->varp()->isGenVar() && !m_underGenFor) { + nodep->v3error("Genvar " + << nodep->prettyNameQ() + << " used outside generate for loop (IEEE 1800-2023 27.4)"); + } + if (nodep->varp()->isRandC() && m_randcIllegalp) { + nodep->v3error("Randc variables not allowed in " + << m_randcIllegalWhy << '\n' + << nodep->warnContextPrimary() << '\n' + << m_randcIllegalp->warnOther() + << "... Location of restricting expression\n" + << m_randcIllegalp->warnContextSecondary()); + } } iterateChildren(nodep); } diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 4067cff6b..a6c259d6d 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -131,8 +131,6 @@ class RandomizeMarkVisitor final : public VNVisitor { BaseToDerivedMap m_baseToDerivedMap; // Mapping from base classes to classes that extend them AstClass* m_classp = nullptr; // Current class - AstConstraintBefore* m_constraintBeforep = nullptr; // Current before constraint - AstConstraintExpr* m_constraintExprp = nullptr; // Current constraint expression AstNode* m_constraintExprGenp = nullptr; // Current constraint or constraint if expression AstNodeModule* m_modp; // Current module AstNodeStmt* m_stmtp = nullptr; // Current statement @@ -403,14 +401,7 @@ class RandomizeMarkVisitor final : public VNVisitor { } } } - void visit(AstConstraintBefore* nodep) override { - VL_RESTORER(m_constraintBeforep); - m_constraintBeforep = nodep; - iterateChildrenConst(nodep); - } void visit(AstConstraintExpr* nodep) override { - VL_RESTORER(m_constraintExprp); - m_constraintExprp = nodep; VL_RESTORER(m_constraintExprGenp); m_constraintExprGenp = nodep; iterateChildrenConst(nodep); @@ -425,15 +416,6 @@ class RandomizeMarkVisitor final : public VNVisitor { iterateAndNextConstNull(nodep->elsesp()); } void visit(AstNodeVarRef* nodep) override { - if (nodep->varp()->isRandC()) { - if (m_constraintExprp && m_constraintExprp->isSoft()) { - nodep->v3error( - "Randc variables not allowed in 'constraint soft' (IEEE 1800-2023 18.5.13.1)"); - } else if (m_constraintBeforep) { - nodep->v3error( - "Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9)"); - } - } if (!m_constraintExprGenp) return; if (nodep->varp()->lifetime().isStatic()) m_staticRefs.emplace(nodep); diff --git a/test_regress/t/t_constraint_before_randc_bad.out b/test_regress/t/t_constraint_before_randc_bad.out new file mode 100644 index 000000000..4cbf1a3a8 --- /dev/null +++ b/test_regress/t/t_constraint_before_randc_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_before_randc_bad.v:11:45: Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9) + 11 | constraint raint2_bad { solve b1 before b2; } + | ^~ + t/t_constraint_before_randc_bad.v:11:29: ... Location of restricting expression + 11 | constraint raint2_bad { solve b1 before b2; } + | ^~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_before_randc_bad.py b/test_regress/t/t_constraint_before_randc_bad.py similarity index 100% rename from test_regress/t/t_randomize_before_randc_bad.py rename to test_regress/t/t_constraint_before_randc_bad.py diff --git a/test_regress/t/t_randomize_before_randc_bad.v b/test_regress/t/t_constraint_before_randc_bad.v similarity index 100% rename from test_regress/t/t_randomize_before_randc_bad.v rename to test_regress/t/t_constraint_before_randc_bad.v diff --git a/test_regress/t/t_constraint_dist_randc_bad.out b/test_regress/t/t_constraint_dist_randc_bad.out new file mode 100644 index 000000000..faff6e9be --- /dev/null +++ b/test_regress/t/t_constraint_dist_randc_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_dist_randc_bad.v:10:23: Randc variables not allowed in 'constraint dist' (IEEE 1800-2023 18.5.3) + 10 | constraint c_bad { rc dist {3 := 0, 10 := 5}; } + | ^~ + t/t_constraint_dist_randc_bad.v:10:26: ... Location of restricting expression + 10 | constraint c_bad { rc dist {3 := 0, 10 := 5}; } + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_randomize_soft_randc_bad.py b/test_regress/t/t_constraint_dist_randc_bad.py similarity index 100% rename from test_regress/t/t_randomize_soft_randc_bad.py rename to test_regress/t/t_constraint_dist_randc_bad.py diff --git a/test_regress/t/t_constraint_dist_randc_bad.v b/test_regress/t/t_constraint_dist_randc_bad.v new file mode 100644 index 000000000..40cd2a770 --- /dev/null +++ b/test_regress/t/t_constraint_dist_randc_bad.v @@ -0,0 +1,14 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls1; + randc int rc; + + constraint c_bad { rc dist {3 := 0, 10 := 5}; } // Bad, no dist on randc +endclass + +module t (/*AUTOARG*/); +endmodule diff --git a/test_regress/t/t_constraint_soft_randc_bad.out b/test_regress/t/t_constraint_soft_randc_bad.out new file mode 100644 index 000000000..d87a61b02 --- /dev/null +++ b/test_regress/t/t_constraint_soft_randc_bad.out @@ -0,0 +1,7 @@ +%Error: t/t_constraint_soft_randc_bad.v:10:28: Randc variables not allowed in 'constraint soft' (IEEE 1800-2023 18.5.13.1) + 10 | constraint c_bad { soft rc > 4; } + | ^~ + t/t_constraint_soft_randc_bad.v:10:23: ... Location of restricting expression + 10 | constraint c_bad { soft rc > 4; } + | ^~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_constraint_soft_randc_bad.py b/test_regress/t/t_constraint_soft_randc_bad.py new file mode 100755 index 000000000..30c3d4f77 --- /dev/null +++ b/test_regress/t/t_constraint_soft_randc_bad.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('linter') + +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_randomize_soft_randc_bad.v b/test_regress/t/t_constraint_soft_randc_bad.v similarity index 100% rename from test_regress/t/t_randomize_soft_randc_bad.v rename to test_regress/t/t_constraint_soft_randc_bad.v diff --git a/test_regress/t/t_randomize_before_randc_bad.out b/test_regress/t/t_randomize_before_randc_bad.out deleted file mode 100644 index 9480b7624..000000000 --- a/test_regress/t/t_randomize_before_randc_bad.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error: t/t_randomize_before_randc_bad.v:11:45: Randc variables not allowed in 'solve before' (IEEE 1800-2023 18.5.9) - : ... note: In instance 't' - 11 | constraint raint2_bad { solve b1 before b2; } - | ^~ -%Error: Exiting due to diff --git a/test_regress/t/t_randomize_soft_randc_bad.out b/test_regress/t/t_randomize_soft_randc_bad.out deleted file mode 100644 index a1646e725..000000000 --- a/test_regress/t/t_randomize_soft_randc_bad.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error: t/t_randomize_soft_randc_bad.v:10:28: Randc variables not allowed in 'constraint soft' (IEEE 1800-2023 18.5.13.1) - : ... note: In instance 't' - 10 | constraint c_bad { soft rc > 4; } - | ^~ -%Error: Exiting due to From 6aa7123a8c34d1d853b84a5e407e4348ff8da501 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 14 Dec 2024 12:49:42 -0500 Subject: [PATCH 151/171] Internals: Function/variable renames. No functional change. --- src/V3LinkDot.cpp | 88 ++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 55f591aa8..60f4ca3e3 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -2400,66 +2400,62 @@ class LinkDotResolveVisitor final : public VNVisitor { } return classSymp; } - void importImplementsClass(AstClass* implementsClassp, VSymEnt* interfaceSymp, - AstClass* baseClassp) { + void importDerivedClass(AstClass* derivedClassp, VSymEnt* baseSymp, AstClass* baseClassp) { // Also used for standard 'extends' from a base class - UINFO(8, indent() << "importImplementsClass to " << implementsClassp << " from " - << baseClassp << endl); - for (VSymEnt::const_iterator it = interfaceSymp->begin(); it != interfaceSymp->end(); - ++it) { - if (AstNode* interfaceSubp = it->second->nodep()) { - UINFO(8, indent() << " SymFunc " << interfaceSubp << endl); + UINFO(8, indent() << "importDerivedClass to " << derivedClassp << " from " << baseClassp + << endl); + for (VSymEnt::const_iterator it = baseSymp->begin(); it != baseSymp->end(); ++it) { + if (AstNode* baseSubp = it->second->nodep()) { + UINFO(8, indent() << " SymFunc " << baseSubp << endl); const string impOrExtends = baseClassp->isInterfaceClass() ? " implements " : " extends "; - if (VN_IS(interfaceSubp, NodeFTask)) { - const VSymEnt* const foundp = m_curSymp->findIdFlat(interfaceSubp->name()); - const AstNodeFTask* const interfaceFuncp = VN_CAST(interfaceSubp, NodeFTask); - if (!interfaceFuncp || !interfaceFuncp->pureVirtual()) continue; - bool existsInChild = foundp && !foundp->imported(); - if (!existsInChild && !implementsClassp->isInterfaceClass()) { - implementsClassp->v3error( - "Class " << implementsClassp->prettyNameQ() << impOrExtends + if (VN_IS(baseSubp, NodeFTask)) { + const VSymEnt* const foundp = m_curSymp->findIdFlat(baseSubp->name()); + const AstNodeFTask* const baseFuncp = VN_CAST(baseSubp, NodeFTask); + if (!baseFuncp || !baseFuncp->pureVirtual()) continue; + bool existsInDerived = foundp && !foundp->imported(); + if (!existsInDerived && !derivedClassp->isInterfaceClass()) { + derivedClassp->v3error( + "Class " << derivedClassp->prettyNameQ() << impOrExtends << baseClassp->prettyNameQ() << " but is missing implementation for " - << interfaceSubp->prettyNameQ() << " (IEEE 1800-2023 8.26)\n" - << implementsClassp->warnContextPrimary() << '\n' - << interfaceSubp->warnOther() + << baseSubp->prettyNameQ() << " (IEEE 1800-2023 8.26)\n" + << derivedClassp->warnContextPrimary() << '\n' + << baseSubp->warnOther() << "... Location of interface class's function\n" - << interfaceSubp->warnContextSecondary()); + << baseSubp->warnContextSecondary()); } - const auto itn = m_ifClassImpNames.find(interfaceSubp->name()); - if (!existsInChild && itn != m_ifClassImpNames.end() - && itn->second != interfaceSubp) { // Not exact same function from diamond - implementsClassp->v3error( - "Class " << implementsClassp->prettyNameQ() << impOrExtends + const auto itn = m_ifClassImpNames.find(baseSubp->name()); + if (!existsInDerived && itn != m_ifClassImpNames.end() + && itn->second != baseSubp) { // Not exact same function from diamond + derivedClassp->v3error( + "Class " << derivedClassp->prettyNameQ() << impOrExtends << baseClassp->prettyNameQ() << " but missing inheritance conflict resolution for " - << interfaceSubp->prettyNameQ() - << " (IEEE 1800-2023 8.26.6.2)\n" - << implementsClassp->warnContextPrimary() << '\n' - << interfaceSubp->warnOther() + << baseSubp->prettyNameQ() << " (IEEE 1800-2023 8.26.6.2)\n" + << derivedClassp->warnContextPrimary() << '\n' + << baseSubp->warnOther() << "... Location of interface class's function\n" - << interfaceSubp->warnContextSecondary()); + << baseSubp->warnContextSecondary()); } - m_ifClassImpNames.emplace(interfaceSubp->name(), interfaceSubp); + m_ifClassImpNames.emplace(baseSubp->name(), baseSubp); } - if (VN_IS(interfaceSubp, Constraint)) { - const VSymEnt* const foundp = m_curSymp->findIdFlat(interfaceSubp->name()); - const AstConstraint* const interfaceFuncp = VN_CAST(interfaceSubp, Constraint); - if (!interfaceFuncp || !interfaceFuncp->isKwdPure()) continue; - bool existsInChild = foundp && !foundp->imported(); - if (!existsInChild && !implementsClassp->isInterfaceClass() - && !implementsClassp->isVirtual()) { - implementsClassp->v3error( - "Class " << implementsClassp->prettyNameQ() << impOrExtends + if (VN_IS(baseSubp, Constraint)) { + const VSymEnt* const foundp = m_curSymp->findIdFlat(baseSubp->name()); + const AstConstraint* const baseFuncp = VN_CAST(baseSubp, Constraint); + if (!baseFuncp || !baseFuncp->isKwdPure()) continue; + bool existsInDerived = foundp && !foundp->imported(); + if (!existsInDerived && !derivedClassp->isInterfaceClass() + && !derivedClassp->isVirtual()) { + derivedClassp->v3error( + "Class " << derivedClassp->prettyNameQ() << impOrExtends << baseClassp->prettyNameQ() << " but is missing constraint implementation for " - << interfaceSubp->prettyNameQ() - << " (IEEE 1800-2023 18.5.2)\n" - << implementsClassp->warnContextPrimary() << '\n' - << interfaceSubp->warnOther() + << baseSubp->prettyNameQ() << " (IEEE 1800-2023 18.5.2)\n" + << derivedClassp->warnContextPrimary() << '\n' + << baseSubp->warnOther() << "... Location of interface class's pure constraint\n" - << interfaceSubp->warnContextSecondary()); + << baseSubp->warnContextSecondary()); } } } @@ -2468,7 +2464,7 @@ class LinkDotResolveVisitor final : public VNVisitor { void importSymbolsFromExtended(AstClass* const nodep, AstClassExtends* const cextp) { AstClass* const baseClassp = cextp->classp(); VSymEnt* const srcp = m_statep->getNodeSym(baseClassp); - importImplementsClass(nodep, srcp, baseClassp); + importDerivedClass(nodep, srcp, baseClassp); if (!cextp->isImplements()) m_curSymp->importFromClass(m_statep->symsp(), srcp); } void classExtendImport(AstClass* nodep) { From 4b4ca90c710f7f73fe1ac308752cc1a9d517f8fb Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 15 Dec 2024 09:15:49 -0500 Subject: [PATCH 152/171] Internals: Create FuncRef/TaskRef directly from Func/Task pointer. No functional change intended --- src/V3AstInlines.h | 22 +++++++++++++++++----- src/V3AstNodeExpr.h | 2 ++ src/V3Fork.cpp | 4 +--- src/V3Randomize.cpp | 38 ++++++++++++-------------------------- src/V3Task.cpp | 7 ++----- src/V3Width.cpp | 10 ++++------ 6 files changed, 38 insertions(+), 45 deletions(-) diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 8759e1bea..8c5d67b49 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -77,6 +77,12 @@ int AstNodeArrayDType::lo() const VL_MT_STABLE { return rangep()->loConst(); } int AstNodeArrayDType::elementsConst() const VL_MT_STABLE { return rangep()->elementsConst(); } VNumRange AstNodeArrayDType::declRange() const VL_MT_STABLE { return VNumRange{left(), right()}; } +AstFuncRef::AstFuncRef(FileLine* fl, AstFunc* taskp, AstNodeExpr* pinsp) + : ASTGEN_SUPER_FuncRef(fl, taskp->name(), pinsp) { + this->taskp(taskp); + dtypeFrom(taskp); +} + AstRange::AstRange(FileLine* fl, int left, int right) : ASTGEN_SUPER_Range(fl) { leftp(new AstConst{fl, static_cast(left)}); @@ -96,11 +102,6 @@ int AstRange::rightConst() const VL_MT_STABLE { return (constp ? constp->toSInt() : 0); } -int AstQueueDType::boundConst() const VL_MT_STABLE { - AstConst* const constp = VN_CAST(boundp(), Const); - return (constp ? constp->toSInt() : 0); -} - AstPin::AstPin(FileLine* fl, int pinNum, AstVarRef* varname, AstNode* exprp) : ASTGEN_SUPER_Pin(fl) , m_pinNum{pinNum} @@ -127,6 +128,17 @@ AstPackArrayDType::AstPackArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* widthForce(width, width); } +int AstQueueDType::boundConst() const VL_MT_STABLE { + AstConst* const constp = VN_CAST(boundp(), Const); + return (constp ? constp->toSInt() : 0); +} + +AstTaskRef::AstTaskRef(FileLine* fl, AstTask* taskp, AstNodeExpr* pinsp) + : ASTGEN_SUPER_TaskRef(fl, taskp->name(), pinsp) { + this->taskp(taskp); + dtypeSetVoid(); +} + int AstBasicDType::hi() const { return (rangep() ? rangep()->hiConst() : m.m_nrange.hi()); } int AstBasicDType::lo() const { return (rangep() ? rangep()->loConst() : m.m_nrange.lo()); } int AstBasicDType::elements() const { diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index a97853dd2..00ab118b6 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -4375,6 +4375,7 @@ class AstFuncRef final : public AstNodeFTaskRef { // A reference to a function bool m_superReference = false; // Called with super reference public: + inline AstFuncRef(FileLine* fl, AstFunc* taskp, AstNodeExpr* pinsp); AstFuncRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp) : ASTGEN_SUPER_FuncRef(fl, (AstNode*)namep, pinsp) {} AstFuncRef(FileLine* fl, const string& name, AstNodeExpr* pinsp) @@ -4415,6 +4416,7 @@ class AstTaskRef final : public AstNodeFTaskRef { // A reference to a task bool m_superReference = false; // Called with super reference public: + inline AstTaskRef(FileLine* fl, AstTask* taskp, AstNodeExpr* pinsp); AstTaskRef(FileLine* fl, AstParseRef* namep, AstNodeExpr* pinsp) : ASTGEN_SUPER_TaskRef(fl, (AstNode*)namep, pinsp) { dtypeSetVoid(); diff --git a/src/V3Fork.cpp b/src/V3Fork.cpp index 30dc0fa82..21485ce98 100644 --- a/src/V3Fork.cpp +++ b/src/V3Fork.cpp @@ -603,9 +603,7 @@ class ForkVisitor final : public VNVisitor { m_modp->addStmtsp(taskp); UINFO(9, "new " << taskp << endl); - AstTaskRef* const taskrefp - = new AstTaskRef{nodep->fileline(), taskp->name(), m_capturedVarRefsp}; - taskrefp->taskp(taskp); + AstTaskRef* const taskrefp = new AstTaskRef{nodep->fileline(), taskp, m_capturedVarRefsp}; AstStmtExpr* const taskcallp = taskrefp->makeStmt(); // Replaced nodes will be revisited, so we don't need to "lift" the arguments // as captures in case of nested forks. diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index a6c259d6d..15cfccf47 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -1105,13 +1105,11 @@ class CaptureVisitor final : public VNVisitor { AstNodeExpr* const pinsp = nodep->pinsp() ? nodep->pinsp()->unlinkFrBackWithNext() : nullptr; AstNodeFTaskRef* taskRefp = nullptr; - if (VN_IS(nodep->taskp(), Task)) - taskRefp = new AstTaskRef{nodep->fileline(), nodep->name(), pinsp}; - else if (VN_IS(nodep->taskp(), Func)) - taskRefp = new AstFuncRef{nodep->fileline(), nodep->name(), pinsp}; + if (AstTask* const taskp = VN_CAST(nodep->taskp(), Task)) + taskRefp = new AstTaskRef{nodep->fileline(), taskp, pinsp}; + else if (AstFunc* const taskp = VN_CAST(nodep->taskp(), Func)) + taskRefp = new AstFuncRef{nodep->fileline(), taskp, pinsp}; UASSERT_OBJ(taskRefp, nodep, "Node needs to point to regular method"); - taskRefp->taskp(nodep->taskp()); - taskRefp->dtypep(nodep->dtypep()); fixupClassOrPackage(nodep->taskp(), taskRefp); taskRefp->user1(nodep->user1()); nodep->replaceWith(taskRefp); @@ -1596,9 +1594,7 @@ class RandomizeVisitor final : public VNVisitor { } void addPrePostCall(AstClass* const classp, AstFunc* const funcp, const string& name) { if (AstTask* userFuncp = VN_CAST(m_memberMap.findMember(classp, name), Task)) { - AstTaskRef* const callp - = new AstTaskRef{userFuncp->fileline(), userFuncp->name(), nullptr}; - callp->taskp(userFuncp); + AstTaskRef* const callp = new AstTaskRef{userFuncp->fileline(), userFuncp, nullptr}; funcp->addStmtsp(callp->makeStmt()); } } @@ -1940,8 +1936,7 @@ class RandomizeVisitor final : public VNVisitor { constrp->user2p(taskp); } AstTaskRef* const setupTaskRefp - = new AstTaskRef{constrp->fileline(), taskp->name(), nullptr}; - setupTaskRefp->taskp(taskp); + = new AstTaskRef{constrp->fileline(), taskp, nullptr}; setupTaskRefp->classOrPackagep(classp); AstTask* const setupAllTaskp = getCreateConstraintSetupFunc(nodep); @@ -1951,8 +1946,7 @@ class RandomizeVisitor final : public VNVisitor { if (AstTask* const resizeTaskp = VN_CAST(constrp->user3p(), Task)) { AstTask* const resizeAllTaskp = getCreateAggrResizeTask(nodep); AstTaskRef* const resizeTaskRefp - = new AstTaskRef{constrp->fileline(), resizeTaskp->name(), nullptr}; - resizeTaskRefp->taskp(resizeTaskp); + = new AstTaskRef{constrp->fileline(), resizeTaskp, nullptr}; resizeTaskRefp->classOrPackagep(classp); resizeAllTaskp->addStmtsp(resizeTaskRefp->makeStmt()); } @@ -1965,8 +1959,7 @@ class RandomizeVisitor final : public VNVisitor { }); randomizep->addStmtsp(implementConstraintsClear(fl, genp)); AstTask* setupAllTaskp = getCreateConstraintSetupFunc(nodep); - AstTaskRef* const setupTaskRefp = new AstTaskRef{fl, setupAllTaskp->name(), nullptr}; - setupTaskRefp->taskp(setupAllTaskp); + AstTaskRef* const setupTaskRefp = new AstTaskRef{fl, setupAllTaskp, nullptr}; randomizep->addStmtsp(setupTaskRefp->makeStmt()); AstNodeModule* const genModp = VN_AS(genp->user2p(), NodeModule); @@ -1994,17 +1987,14 @@ class RandomizeVisitor final : public VNVisitor { if (AstTask* const resizeAllTaskp = VN_AS(m_memberMap.findMember(nodep, "__Vresize_constrained_arrays"), Task)) { - AstTaskRef* const resizeTaskRefp = new AstTaskRef{fl, resizeAllTaskp->name(), nullptr}; - resizeTaskRefp->taskp(resizeAllTaskp); + AstTaskRef* const resizeTaskRefp = new AstTaskRef{fl, resizeAllTaskp, nullptr}; randomizep->addStmtsp(resizeTaskRefp->makeStmt()); } AstFunc* const basicRandomizep = V3Randomize::newRandomizeFunc(m_memberMap, nodep, "__Vbasic_randomize"); addBasicRandomizeBody(basicRandomizep, nodep, randModeVarp); - AstFuncRef* const basicRandomizeCallp = new AstFuncRef{fl, "__Vbasic_randomize", nullptr}; - basicRandomizeCallp->taskp(basicRandomizep); - basicRandomizeCallp->dtypep(basicRandomizep->dtypep()); + AstFuncRef* const basicRandomizeCallp = new AstFuncRef{fl, basicRandomizep, nullptr}; AstVarRef* const fvarRefReadp = fvarRefp->cloneTree(false); fvarRefReadp->access(VAccess::READ); @@ -2176,16 +2166,12 @@ class RandomizeVisitor final : public VNVisitor { AstFunc* const basicRandomizeFuncp = V3Randomize::newRandomizeFunc(m_memberMap, classp, "__Vbasic_randomize"); AstFuncRef* const basicRandomizeFuncCallp - = new AstFuncRef{nodep->fileline(), "__Vbasic_randomize", nullptr}; - basicRandomizeFuncCallp->taskp(basicRandomizeFuncp); - basicRandomizeFuncCallp->dtypep(basicRandomizeFuncp->dtypep()); + = new AstFuncRef{nodep->fileline(), basicRandomizeFuncp, nullptr}; // Copy (derive) class constraints if present if (classGenp) { AstTask* const constrSetupFuncp = getCreateConstraintSetupFunc(classp); - AstTaskRef* const callp - = new AstTaskRef{nodep->fileline(), constrSetupFuncp->name(), nullptr}; - callp->taskp(constrSetupFuncp); + AstTaskRef* const callp = new AstTaskRef{nodep->fileline(), constrSetupFuncp, nullptr}; randomizeFuncp->addStmtsp(callp->makeStmt()); randomizeFuncp->addStmtsp(new AstAssign{ nodep->fileline(), new AstVarRef{nodep->fileline(), localGenp, VAccess::WRITE}, diff --git a/src/V3Task.cpp b/src/V3Task.cpp index b54af15c1..a0aac92a6 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -1849,16 +1849,13 @@ AstNodeFTask* V3Task::taskConnectWrapNew(AstNodeFTask* taskp, const string& newn newFVarp->name(newTaskp->name()); newTaskp->fvarp(newFVarp); newTaskp->dtypeFrom(newFVarp); - newCallp = new AstFuncRef{taskp->fileline(), taskp->name(), nullptr}; - newCallp->taskp(taskp); - newCallp->dtypeFrom(newFVarp); + newCallp = new AstFuncRef{taskp->fileline(), VN_AS(taskp, Func), nullptr}; newCallInsertp = new AstAssign{taskp->fileline(), new AstVarRef{fvarp->fileline(), newFVarp, VAccess::WRITE}, newCallp}; newCallInsertp->dtypeFrom(newFVarp); } else if (VN_IS(taskp, Task)) { - newCallp = new AstTaskRef{taskp->fileline(), taskp->name(), nullptr}; - newCallp->taskp(taskp); + newCallp = new AstTaskRef{taskp->fileline(), VN_AS(taskp, Task), nullptr}; newCallInsertp = new AstStmtExpr{taskp->fileline(), newCallp}; } else { taskp->v3fatalSrc("Unsupported: Non-constant default value in missing argument in a " diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 51848261c..bb91fc3c6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -3788,11 +3788,10 @@ class WidthVisitor final : public VNVisitor { if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNodeFTaskRef* newp = nullptr; if (VN_IS(ftaskp, Task)) { - newp = new AstTaskRef{nodep->fileline(), ftaskp->name(), argsp}; + newp = new AstTaskRef{nodep->fileline(), VN_AS(ftaskp, Task), argsp}; } else { - newp = new AstFuncRef{nodep->fileline(), ftaskp->name(), argsp}; + newp = new AstFuncRef{nodep->fileline(), VN_AS(ftaskp, Func), argsp}; } - newp->taskp(ftaskp); newp->classOrPackagep(ifacep); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); @@ -3927,11 +3926,10 @@ class WidthVisitor final : public VNVisitor { if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNodeFTaskRef* newp = nullptr; if (VN_IS(ftaskp, Task)) { - newp = new AstTaskRef{nodep->fileline(), ftaskp->name(), argsp}; + newp = new AstTaskRef{nodep->fileline(), VN_AS(ftaskp, Task), argsp}; } else { - newp = new AstFuncRef{nodep->fileline(), ftaskp->name(), argsp}; + newp = new AstFuncRef{nodep->fileline(), VN_AS(ftaskp, Func), argsp}; } - newp->taskp(ftaskp); newp->classOrPackagep(classp); nodep->replaceWith(newp); VL_DO_DANGLING(nodep->deleteTree(), nodep); From c7355b40567aecfef5e6007d5a7154985ef7bdd0 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sun, 15 Dec 2024 09:19:30 -0500 Subject: [PATCH 153/171] Commentary: Changes update --- Changes | 7 +++++++ docs/spelling.txt | 1 + 2 files changed, 8 insertions(+) diff --git a/Changes b/Changes index 0ced35e20..837d21fe6 100644 --- a/Changes +++ b/Changes @@ -18,6 +18,7 @@ Verilator 5.031 devel * Support vpiDefName (#3906) (#5572). [Krzysztof Starecki] * Support parameter names in pattern initialization (#5593) (#5596). [Greg Davill] * Support randomize size constraints with restrictions (#5582 partial) (#5611). [Ryszard Rozak, Antmicro Ltd.] +* Support associative array basic constrained randomization (#5658) (#5670). [Yilou Wang] * Support `default disable iff` and `$inferred_disable` (#4016). [Srinivasan Venkataramanan] * Support `extern constraint` and `pure constraint`. * Add `--no-std-waiver` and default reading of standard lint waivers file (#5607). @@ -34,9 +35,11 @@ Verilator 5.031 devel * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add error on `solve before` or soft constraints of `randc` variable. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] +* Improve optimization of duplicate wide expressions (#5637). [Bartłomiej Chmiel, Antmicro Ltd.] * Fix dotted reference in delay value (#2410). * Fix `function fork...join_none` regression with unknown type (#4449). * Fix public_module requiring a wire to become public (#4916). [Andrew Nolte] +* Fix --hierarchical on projects with dot-f dependency lists (#5199) (#5669). [Bartłomiej Chmiel, Antmicro Ltd.] * Fix can't locate scope error in interface task delayed assignment (#5462) (#5568). [Zhou Shen] * Fix BLKANDNBLK for for VARXREFs (#5569). [Todd Strader] * Fix VPI error instead of fatal for vpi_get_value() on large signals (#5571). [Todd Strader] @@ -49,6 +52,10 @@ Verilator 5.031 devel * Fix array of struct member overwrites on member update (#5605) (#5618) (#5628). [sumpster] * Fix interface and struct pattern collision (#5639) (#5640). [Todd Strader] * Fix mis-aliasing of instances with mailbox parameter types (#5632 partial). +* Fix error on duplicated declaration of gen block (#5663). [Ryszard Rozak, Antmicro Ltd.] +* Fix wildcard equality and inside operators for non-fourstate expressions (#5673). [Ryszard Rozak, Antmicro Ltd.] +* Fix `randomize..with` of parameterized classes (#5676). [Ryszard Rozak, Antmicro Ltd.] +* Fix interface bracketed array parameter access (#5677) (#5678). [Todd Strader] Verilator 5.030 2024-10-27 diff --git a/docs/spelling.txt b/docs/spelling.txt index 76b0bec90..6af921da4 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -693,6 +693,7 @@ fno fopen forceable foreach +fourstate fprintf fprofile fread From 29fb82d3b792369dad7d488b8191071e3c01076f Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 16 Dec 2024 18:02:17 -0500 Subject: [PATCH 154/171] Commentary --- docs/guide/exe_verilator_coverage.rst | 6 +++--- docs/guide/exe_verilator_gantt.rst | 11 +++++++++++ docs/guide/exe_verilator_profcfunc.rst | 11 +++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/guide/exe_verilator_coverage.rst b/docs/guide/exe_verilator_coverage.rst index ddfd8aa93..4f9f1be84 100644 --- a/docs/guide/exe_verilator_coverage.rst +++ b/docs/guide/exe_verilator_coverage.rst @@ -35,11 +35,11 @@ verilator_coverage Example Usage verilator_coverage --help verilator_coverage --version - verilator_coverage --annotate + verilator_coverage --annotate obj_dir coverage.dat - verilator_coverage -write merged.dat ... + verilator_coverage --write merged.dat coverage.dat ... - verilator_coverage -write-info merged.info ... + verilator_coverage --write-info merged.info coverage.dat ... verilator_coverage Arguments diff --git a/docs/guide/exe_verilator_gantt.rst b/docs/guide/exe_verilator_gantt.rst index 6088154b2..e1275d9c7 100644 --- a/docs/guide/exe_verilator_gantt.rst +++ b/docs/guide/exe_verilator_gantt.rst @@ -62,6 +62,17 @@ predicted_thread#_mtask executing. +verilator_gantt Example Usage +----------------------------- + +.. + + verilator_gantt --help + verilator_gantt --version + + verilator_gantt profile_exec.dat + + verilator_gantt Arguments ------------------------- diff --git a/docs/guide/exe_verilator_profcfunc.rst b/docs/guide/exe_verilator_profcfunc.rst index 815109dab..ec2548e01 100644 --- a/docs/guide/exe_verilator_profcfunc.rst +++ b/docs/guide/exe_verilator_profcfunc.rst @@ -15,6 +15,17 @@ reported as a rounding error. For an overview of the use of verilator_profcfunc, see :ref:`Profiling`. +verilator_profcfunc Example Usage +--------------------------------- + +.. + + verilator_profcfunc --help + verilator_profcfunc --version + + verilator_profcfunc gprof.out + + verilator_profcfunc Arguments ----------------------------- From c093b243424dc17338e7bf2cbb9c42ee1cf2a373 Mon Sep 17 00:00:00 2001 From: Ryszard Rozak Date: Thu, 19 Dec 2024 15:51:51 +0100 Subject: [PATCH 155/171] Fix width extension of operands of `inside` operator (#5685) --- src/V3Width.cpp | 16 ++++++++++------ test_regress/t/t_inside_extend.py | 18 ++++++++++++++++++ test_regress/t/t_inside_extend.v | 21 +++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100755 test_regress/t/t_inside_extend.py create mode 100644 test_regress/t/t_inside_extend.v diff --git a/src/V3Width.cpp b/src/V3Width.cpp index bb91fc3c6..59c64c97a 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2670,33 +2670,37 @@ class WidthVisitor final : public VNVisitor { } AstBasicDType* dtype = VN_CAST(nodep->exprp()->dtypep(), BasicDType); - AstNodeDType* subDTypep = nullptr; + AstNodeDType* expDTypep = nullptr; if (dtype && dtype->isString()) { nodep->dtypeSetString(); - subDTypep = nodep->findStringDType(); + expDTypep = nodep->findStringDType(); } else if (dtype && dtype->isDouble()) { nodep->dtypeSetDouble(); - subDTypep = nodep->findDoubleDType(); + expDTypep = nodep->findDoubleDType(); } else { // Take width as maximum across all items int width = nodep->exprp()->width(); int mwidth = nodep->exprp()->widthMin(); + bool isFourstate = nodep->exprp()->dtypep()->isFourstate(); for (const AstNode* itemp = nodep->itemsp(); itemp; itemp = itemp->nextp()) { width = std::max(width, itemp->width()); mwidth = std::max(mwidth, itemp->widthMin()); + isFourstate |= itemp->dtypep()->isFourstate(); } nodep->dtypeSetBit(); - subDTypep = nodep->findLogicDType(width, mwidth, nodep->exprp()->dtypep()->numeric()); + const VSigning numeric = nodep->exprp()->dtypep()->numeric(); + expDTypep = isFourstate ? nodep->findLogicDType(width, mwidth, numeric) + : nodep->findBitDType(width, mwidth, numeric); } - iterateCheck(nodep, "Inside expression", nodep->exprp(), CONTEXT_DET, FINAL, subDTypep, + iterateCheck(nodep, "Inside expression", nodep->exprp(), CONTEXT_DET, FINAL, expDTypep, EXTEND_EXP); for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) { nextip = itemp->nextp(); // iterate may cause the node to get replaced // InsideRange will get replaced with Lte&Gte and finalized later if (!VN_IS(itemp, InsideRange)) - iterateCheck(nodep, "Inside Item", itemp, CONTEXT_DET, FINAL, subDTypep, + iterateCheck(nodep, "Inside Item", itemp, CONTEXT_DET, FINAL, expDTypep, EXTEND_EXP); } diff --git a/test_regress/t/t_inside_extend.py b/test_regress/t/t_inside_extend.py new file mode 100755 index 000000000..78d425f95 --- /dev/null +++ b/test_regress/t/t_inside_extend.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile(verilator_flags2=["-Wno-WIDTH"]) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_inside_extend.v b/test_regress/t/t_inside_extend.v new file mode 100644 index 000000000..e388cdb58 --- /dev/null +++ b/test_regress/t/t_inside_extend.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Antmicro. +// SPDX-License-Identifier: CC0-1.0 + +typedef enum bit [4:0] {V0 = 1} my_enum; +class Cls; + my_enum sp = V0; +endclass + +module t (/*AUTOARG*/); + initial begin + Cls c = new; + int i = 0; + if (i inside {c.sp}) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule From 8a9fc9237d42e93ffd16d113a63357d2bd306a57 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 19 Dec 2024 15:01:57 -0500 Subject: [PATCH 156/171] Tests: Execute t_emit_accessors (#5689) (#5688) --- test_regress/t/t_emit_accessors.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test_regress/t/t_emit_accessors.py b/test_regress/t/t_emit_accessors.py index a85bb33eb..6bb128038 100755 --- a/test_regress/t/t_emit_accessors.py +++ b/test_regress/t/t_emit_accessors.py @@ -13,4 +13,6 @@ test.scenarios('vlt') test.compile(make_main=False, verilator_flags2=["--emit-accessors", "--exe", test.pli_filename]) +test.execute() + test.passes() From 74d5d008bb626b6a3c6c736206d85defdf70ed00 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 19 Dec 2024 15:15:28 -0500 Subject: [PATCH 157/171] Fix VPI + SYMRSVDWORD intersection (#5686) --- src/V3Ast.cpp | 6 ++++-- test_regress/t/t_vpi_var.cpp | 10 ++++++++++ test_regress/t/t_vpi_var.py | 2 +- test_regress/t/t_vpi_var.v | 3 +++ test_regress/t/t_vpi_var2.py | 2 +- test_regress/t/t_vpi_var2.v | 1 + test_regress/t/t_vpi_var3.v | 1 + 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index d0f41968f..4369b1176 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -222,12 +222,14 @@ string AstNode::vpiName(const string& namein) { // This is slightly different from prettyName, in that when we encounter escaped characters, // we change that identifier to an escaped identifier, wrapping it with '\' and ' ' // as specified in LRM 23.6 + string name = namein; + if (0 == namein.substr(0, 7).compare("__SYM__")) { name = namein.substr(7); } string pretty; - pretty.reserve(namein.length()); + pretty.reserve(name.length()); bool inEscapedIdent = false; int lastIdent = 0; - for (const char* pos = namein.c_str(); *pos;) { + for (const char* pos = name.c_str(); *pos;) { char specialChar = 0; if (pos[0] == '-' && pos[1] == '>') { // -> specialChar = '.'; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 82c98783d..97c123985 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -405,6 +405,16 @@ int _mon_check_var() { CHECK_RESULT_CSTR(p, "vpiConstant"); } + // C++ keyword collision + { + TestVpiHandle vh10 = VPI_HANDLE("nullptr"); + CHECK_RESULT_NZ(vh10); + vpi_get_value(vh10, &tmpValue); + CHECK_RESULT(tmpValue.value.integer, 123); + p = vpi_get_str(vpiType, vh10); + CHECK_RESULT_CSTR(p, "vpiParameter"); + } + // non-integer variables tmpValue.format = vpiRealVal; { diff --git a/test_regress/t/t_vpi_var.py b/test_regress/t/t_vpi_var.py index 14985718b..610e7454d 100755 --- a/test_regress/t/t_vpi_var.py +++ b/test_regress/t/t_vpi_var.py @@ -17,7 +17,7 @@ test.compile(make_top_shell=False, sim_time=2100, iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI -DWAVES"], v_flags2=["+define+USE_VPI_NOT_DPI"], - verilator_flags2=["--exe --vpi --no-l2name", test.pli_filename]) + verilator_flags2=["-Wno-SYMRSVDWORD --exe --vpi --no-l2name", test.pli_filename]) test.execute(use_libvpi=True, all_run_flags=['+PLUS +INT=1234 +STRSTR']) diff --git a/test_regress/t/t_vpi_var.v b/test_regress/t/t_vpi_var.v index 52d92dfc4..d93196cc9 100644 --- a/test_regress/t/t_vpi_var.v +++ b/test_regress/t/t_vpi_var.v @@ -55,6 +55,9 @@ extern "C" int mon_check(); real real1 /*verilator public_flat_rw */; string str1 /*verilator public_flat_rw */; + // specifically public and not public_flat_rw here so as to induce the C++ + // keyword collision + localparam int nullptr /*verilator public */ = 123; sub sub(); diff --git a/test_regress/t/t_vpi_var2.py b/test_regress/t/t_vpi_var2.py index 478afcebb..62511e4cb 100755 --- a/test_regress/t/t_vpi_var2.py +++ b/test_regress/t/t_vpi_var2.py @@ -18,7 +18,7 @@ test.compile(make_top_shell=False, sim_time=2100, iv_flags2=["-g2005-sv -D USE_VPI_NOT_DPI -DWAVES -DT_VPI_VAR2"], v_flags2=["+define+USE_VPI_NOT_DPI"], - verilator_flags2=["--exe --vpi --no-l2name", test.pli_filename]) + verilator_flags2=["-Wno-SYMRSVDWORD --exe --vpi --no-l2name", test.pli_filename]) test.execute(use_libvpi=True, all_run_flags=['+PLUS +INT=1234 +STRSTR']) diff --git a/test_regress/t/t_vpi_var2.v b/test_regress/t/t_vpi_var2.v index 691502419..0c0019ddf 100644 --- a/test_regress/t/t_vpi_var2.v +++ b/test_regress/t/t_vpi_var2.v @@ -74,6 +74,7 @@ extern "C" int mon_check(); /*verilator public_flat_rw_on*/ real real1; string str1; + localparam int nullptr = 123; /*verilator public_off*/ sub sub(); diff --git a/test_regress/t/t_vpi_var3.v b/test_regress/t/t_vpi_var3.v index e81fb48db..a6422b8c2 100644 --- a/test_regress/t/t_vpi_var3.v +++ b/test_regress/t/t_vpi_var3.v @@ -55,6 +55,7 @@ extern "C" int mon_check(); real real1; string str1; + localparam int nullptr = 123; sub sub(); From 5f1df5b3890fb4ea8c9f2ba3e63fbc456ba335a1 Mon Sep 17 00:00:00 2001 From: Anthony Moore Date: Thu, 19 Dec 2024 13:17:44 -0700 Subject: [PATCH 158/171] Add a default CMAKE_BUILD_TYPE (#5691) (#5692) --- CMakeLists.txt | 5 +++++ docs/CONTRIBUTORS | 1 + 2 files changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17a2fefab..24ed3117e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,11 @@ project( LANGUAGES CXX ) +# Set default build type to Release if not specified +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) +endif() + option( DEBUG_AND_RELEASE_AND_COVERAGE "Builds both the debug and release binaries, overriding CMAKE_BUILD_TYPE. Not supported under MSBuild." diff --git a/docs/CONTRIBUTORS b/docs/CONTRIBUTORS index 8824b138f..fa06407a2 100644 --- a/docs/CONTRIBUTORS +++ b/docs/CONTRIBUTORS @@ -20,6 +20,7 @@ Andrei Kostovski Andrew Miloradovsky Andrew Nolte Anthony Donlon +Anthony Moore Arkadiusz Kozdra Arthur Rosa Aylon Chaim Porat From a23fad91a327f59db84d4459a706173254259d73 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 19 Dec 2024 16:29:16 -0500 Subject: [PATCH 159/171] Tests: Reduce test_regress VPI copypasta (#5694) (#5693) --- test_regress/t/TestVpi.h | 44 +++++++++++++++++++++++ test_regress/t/t_vpi_const_type.cpp | 32 ----------------- test_regress/t/t_vpi_get.cpp | 39 -------------------- test_regress/t/t_vpi_memory.cpp | 3 -- test_regress/t/t_vpi_module.cpp | 29 --------------- test_regress/t/t_vpi_module_empty.cpp | 12 ------- test_regress/t/t_vpi_onetime_cbs.cpp | 16 --------- test_regress/t/t_vpi_package.cpp | 32 ----------------- test_regress/t/t_vpi_param.cpp | 44 ----------------------- test_regress/t/t_vpi_public_depth.cpp | 32 ----------------- test_regress/t/t_vpi_repetitive_cbs.cpp | 16 --------- test_regress/t/t_vpi_unimpl.cpp | 48 ------------------------- test_regress/t/t_vpi_var.cpp | 44 ----------------------- 13 files changed, 44 insertions(+), 347 deletions(-) diff --git a/test_regress/t/TestVpi.h b/test_regress/t/TestVpi.h index aa44dda90..a6dfac58d 100644 --- a/test_regress/t/TestVpi.h +++ b/test_regress/t/TestVpi.h @@ -521,3 +521,47 @@ const char* strFromVpiConstType(PLI_INT32 constType) { if (constType < 0) return names[0]; return names[(constType <= vpiTimeConst) ? constType : 0]; } + +#define FILENM basename(strdup(__FILE__)) + +#define CHECK_RESULT_VH(got, exp) \ + if ((got) != (exp)) { \ + printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ + return __LINE__; \ + } + +#define CHECK_RESULT_NZ(got) \ + if (!(got)) { \ + printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ + return __LINE__; \ + } + +#define CHECK_RESULT_Z(got) \ + if (got) { \ + printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ + return __LINE__; \ + } + +// Use cout to avoid issues with %d/%lx etc +#define CHECK_RESULT(got, exp) \ + if ((got) != (exp)) { \ + std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ + << " EXP = " << (exp) << std::endl; \ + return __LINE__; \ + } + +#define CHECK_RESULT_HEX(got, exp) \ + if ((got) != (exp)) { \ + std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << std::hex \ + << ": GOT = " << (got) << " EXP = " << (exp) << std::endl; \ + return __LINE__; \ + } + +#define CHECK_RESULT_CSTR(got, exp) \ + if (std::strcmp((got), (exp))) { \ + printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ + (got) ? (got) : "", (exp) ? (exp) : ""); \ + return __LINE__; \ + } + +#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp) diff --git a/test_regress/t/t_vpi_const_type.cpp b/test_regress/t/t_vpi_const_type.cpp index 6c4c25339..ac8ebd2db 100644 --- a/test_regress/t/t_vpi_const_type.cpp +++ b/test_regress/t/t_vpi_const_type.cpp @@ -35,38 +35,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_const_type.cpp" - -#define DEBUG \ - if (0) printf - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if (got) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - extern "C" { int mon_check() { #ifdef TEST_VERBOSE diff --git a/test_regress/t/t_vpi_get.cpp b/test_regress/t/t_vpi_get.cpp index 1d63845b4..021d761b6 100644 --- a/test_regress/t/t_vpi_get.cpp +++ b/test_regress/t/t_vpi_get.cpp @@ -35,50 +35,11 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_get.cpp" - #define TEST_MSG \ if (0) printf //====================================================================== -#define CHECK_RESULT_VH(got, exp) \ - if ((got) != (exp)) { \ - printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ - return __LINE__; \ - } - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_HEX(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << std::hex \ - << ": GOT = " << (got) << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp) - static int _mon_check_props(TestVpiHandle& handle, int size, int direction, int scalar, int type) { s_vpi_value value; value.format = vpiIntVal; diff --git a/test_regress/t/t_vpi_memory.cpp b/test_regress/t/t_vpi_memory.cpp index 9ef3fbe97..e61cf737a 100644 --- a/test_regress/t/t_vpi_memory.cpp +++ b/test_regress/t/t_vpi_memory.cpp @@ -36,9 +36,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_memory.cpp" - #define DEBUG \ if (0) printf diff --git a/test_regress/t/t_vpi_module.cpp b/test_regress/t/t_vpi_module.cpp index 955464d11..a0a3c030f 100644 --- a/test_regress/t/t_vpi_module.cpp +++ b/test_regress/t/t_vpi_module.cpp @@ -35,38 +35,9 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_module.cpp" - #define DEBUG \ if (0) printf -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if (got) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - void modDump(const TestVpiHandle& it, int n) { while (TestVpiHandle hndl = vpi_scan(it)) { const char* nm = vpi_get_str(vpiName, hndl); diff --git a/test_regress/t/t_vpi_module_empty.cpp b/test_regress/t/t_vpi_module_empty.cpp index 139ff4cce..f08ebb27d 100644 --- a/test_regress/t/t_vpi_module_empty.cpp +++ b/test_regress/t/t_vpi_module_empty.cpp @@ -35,18 +35,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_module_empty.cpp" - -#define DEBUG \ - if (0) printf - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - extern "C" { int mon_check() { #ifdef TEST_VERBOSE diff --git a/test_regress/t/t_vpi_onetime_cbs.cpp b/test_regress/t/t_vpi_onetime_cbs.cpp index dfd0106ed..4e4222967 100644 --- a/test_regress/t/t_vpi_onetime_cbs.cpp +++ b/test_regress/t/t_vpi_onetime_cbs.cpp @@ -54,22 +54,6 @@ bool verbose = true; bool verbose = false; #endif -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", __FILE__, __LINE__); \ - got_error = true; \ - return __LINE__; \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - got_error = true; \ - return __LINE__; \ - } - #define STRINGIFY_CB_CASE(_cb) \ case _cb: return #_cb diff --git a/test_regress/t/t_vpi_package.cpp b/test_regress/t/t_vpi_package.cpp index 7d16c2283..4feb00a48 100644 --- a/test_regress/t/t_vpi_package.cpp +++ b/test_regress/t/t_vpi_package.cpp @@ -35,38 +35,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_package.cpp" - -#define DEBUG \ - if (0) printf - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if (got) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - extern "C" { int count_params(TestVpiHandle& handle, int expectedParams) { TestVpiHandle it = vpi_iterate(vpiParameter, handle); diff --git a/test_regress/t/t_vpi_param.cpp b/test_regress/t/t_vpi_param.cpp index 1f2c5d434..d5700b10a 100644 --- a/test_regress/t/t_vpi_param.cpp +++ b/test_regress/t/t_vpi_param.cpp @@ -42,50 +42,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_param.cpp" - -#define DEBUG \ - if (0) printf - -//====================================================================== - -#define CHECK_RESULT_VH(got, exp) \ - if ((got) != (exp)) { \ - printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ - return __LINE__; \ - } - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_HEX(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << std::hex \ - << ": GOT = " << (got) << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp) - int check_param_int(std::string name, PLI_INT32 format, int exp_value, bool verbose) { int vpi_type; TestVpiHandle param_h; diff --git a/test_regress/t/t_vpi_public_depth.cpp b/test_regress/t/t_vpi_public_depth.cpp index ee1217bd4..cb4da699c 100644 --- a/test_regress/t/t_vpi_public_depth.cpp +++ b/test_regress/t/t_vpi_public_depth.cpp @@ -41,38 +41,6 @@ #include "TestSimulator.h" #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_public_depth.cpp" - -#define DEBUG \ - if (0) printf - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if (got) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - void modDump(const TestVpiHandle& it, int n) { while (TestVpiHandle hndl = vpi_scan(it)) { const char* nm = vpi_get_str(vpiName, hndl); diff --git a/test_regress/t/t_vpi_repetitive_cbs.cpp b/test_regress/t/t_vpi_repetitive_cbs.cpp index aa4c0c204..2cae4f7c5 100644 --- a/test_regress/t/t_vpi_repetitive_cbs.cpp +++ b/test_regress/t/t_vpi_repetitive_cbs.cpp @@ -71,22 +71,6 @@ bool verbose = false; #define END_TEST return __LINE__; #endif -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", __FILE__, __LINE__); \ - got_error = true; \ - END_TEST \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << __FILE__ << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - got_error = true; \ - END_TEST \ - } - #define STRINGIFY_CB_CASE(_cb) \ case _cb: return #_cb diff --git a/test_regress/t/t_vpi_unimpl.cpp b/test_regress/t/t_vpi_unimpl.cpp index 5b85a38e8..c6d73f324 100644 --- a/test_regress/t/t_vpi_unimpl.cpp +++ b/test_regress/t/t_vpi_unimpl.cpp @@ -22,58 +22,10 @@ // These require the above. Comment prevents clang-format moving them #include "TestVpi.h" -// __FILE__ is too long -#define FILENM "t_vpi_unimpl.cpp" - -#define DEBUG \ - if (0) printf - unsigned int callback_count = 0; //====================================================================== -#define CHECK_RESULT_VH(got, exp) \ - if ((got) != (exp)) { \ - printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ - return __LINE__; \ - } - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if (got) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_HEX(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << std::hex \ - << ": GOT = " << (got) << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - (got) ? (got) : "", (exp) ? (exp) : ""); \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp) - int _mon_check_unimpl(p_cb_data cb_data) { static TestVpiHandle cb, clk_h; vpiHandle handle; diff --git a/test_regress/t/t_vpi_var.cpp b/test_regress/t/t_vpi_var.cpp index 97c123985..db721c306 100644 --- a/test_regress/t/t_vpi_var.cpp +++ b/test_regress/t/t_vpi_var.cpp @@ -50,8 +50,6 @@ #include "TestVpi.h" int errors = 0; -// __FILE__ is too long -#define FILENM "t_vpi_var.cpp" #define TEST_MSG \ if (0) printf @@ -65,48 +63,6 @@ unsigned int callback_count_strs_max = 500; //====================================================================== -#define CHECK_RESULT_VH(got, exp) \ - if ((got) != (exp)) { \ - printf("%%Error: %s:%d: GOT = %p EXP = %p\n", FILENM, __LINE__, (got), (exp)); \ - return __LINE__; \ - } - -#define CHECK_RESULT_NZ(got) \ - if (!(got)) { \ - printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -#define CHECK_RESULT_Z(got) \ - if ((got)) { \ - printf("%%Error: %s:%d: GOT = !NULL EXP = NULL\n", FILENM, __LINE__); \ - return __LINE__; \ - } - -// Use cout to avoid issues with %d/%lx etc -#define CHECK_RESULT(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << ": GOT = " << (got) \ - << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_HEX(got, exp) \ - if ((got) != (exp)) { \ - std::cout << std::dec << "%Error: " << FILENM << ":" << __LINE__ << std::hex \ - << ": GOT = " << (got) << " EXP = " << (exp) << std::endl; \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR(got, exp) \ - if (std::strcmp((got), (exp))) { \ - printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", FILENM, __LINE__, \ - ((got) != NULL) ? (got) : "", ((exp) != NULL) ? (exp) : ""); \ - return __LINE__; \ - } - -#define CHECK_RESULT_CSTR_STRIP(got, exp) CHECK_RESULT_CSTR(got + strspn(got, " "), exp) - // We cannot replace those with VL_STRINGIFY, not available when PLI is build #define STRINGIFY(x) STRINGIFY2(x) #define STRINGIFY2(x) #x From 079a53e82007079cf78b822fcc2856791c18280b Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Thu, 19 Dec 2024 17:14:15 -0500 Subject: [PATCH 160/171] Commentary: SYMRSVDWORD + VPI documentation (#5696) --- docs/guide/warnings.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index d86bbc0f8..0f5f7131d 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1692,6 +1692,9 @@ List Of Warnings Warning that a symbol matches a C++ reserved word, and using this as a symbol name would result in odd C++ compiler errors. You may disable this warning, but Verilator will rename the symbol to avoid conflict. + If you are using `--vpi` and only mark things as public for VPI access + (and not C++ access) then it is advisable to disable this warning with + :code:`-Wno-SYMRSVDWORD`. .. option:: SYNCASYNCNET From 62945bb3bc3afd52f19178720b4da7e739428670 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 19 Dec 2024 17:23:44 -0500 Subject: [PATCH 161/171] Commentary: Changes update --- Changes | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Changes b/Changes index 837d21fe6..832991ed6 100644 --- a/Changes +++ b/Changes @@ -33,6 +33,7 @@ Verilator 5.031 devel * Add error on illegal `--prefix` etc. values (#5507). [Fabian Keßler] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] +* Add default CMAKE_BUILD_TYPE (#5691) (#5692). [Anthony Moore] * Add error on `solve before` or soft constraints of `randc` variable. * Improve concatenation performance (#5598) (#5599) (#5602). [Geza Lore] * Improve optimization of duplicate wide expressions (#5637). [Bartłomiej Chmiel, Antmicro Ltd.] @@ -56,6 +57,8 @@ Verilator 5.031 devel * Fix wildcard equality and inside operators for non-fourstate expressions (#5673). [Ryszard Rozak, Antmicro Ltd.] * Fix `randomize..with` of parameterized classes (#5676). [Ryszard Rozak, Antmicro Ltd.] * Fix interface bracketed array parameter access (#5677) (#5678). [Todd Strader] +* Fix width extension of operands of `inside` operator (#5685). [Ryszard Rozak, Antmicro Ltd.] +* Fix VPI + SYMRSVDWORD intersection (#5686). [Todd Strader] Verilator 5.030 2024-10-27 From bb45fd6c6c52984f0a0770c045da67b856dfaa16 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 19 Dec 2024 17:30:40 -0500 Subject: [PATCH 162/171] Add error on `--savable --timing` (#5690). --- Changes | 1 + src/V3Options.cpp | 3 +++ test_regress/t/t_savable_timing_bad.out | 2 ++ test_regress/t/t_savable_timing_bad.py | 20 ++++++++++++++++++++ 4 files changed, 26 insertions(+) create mode 100644 test_regress/t/t_savable_timing_bad.out create mode 100755 test_regress/t/t_savable_timing_bad.py diff --git a/Changes b/Changes index 832991ed6..df06d491b 100644 --- a/Changes +++ b/Changes @@ -31,6 +31,7 @@ Verilator 5.031 devel * Add error on `wait` with missing `.triggered` (#4457). * Add error when improperly storing to parameter (#5147). [Gökçe Aydos] * Add error on illegal `--prefix` etc. values (#5507). [Fabian Keßler] +* Add error on `--savable --timing` (#5690). [Narcis Rodas] * Add coverage point hierarchy to coverage reports (#5575) (#5576). [Andrew Nolte] * Add warning on global constraints (#5625). [Ryszard Rozak, Antmicro Ltd.] * Add default CMAKE_BUILD_TYPE (#5691) (#5692). [Anthony Moore] diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 8131f3c6e..717328b6d 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -949,6 +949,9 @@ void V3Options::notify() VL_MT_DISABLED { if (coverage() && savable()) { cmdfl->v3error("Unsupported: --coverage and --savable not supported together"); } + if (v3Global.opt.timing().isSetTrue() && savable()) { + cmdfl->v3error("Unsupported: --timing and --savable not supported together"); + } // Mark options as available m_available = true; diff --git a/test_regress/t/t_savable_timing_bad.out b/test_regress/t/t_savable_timing_bad.out new file mode 100644 index 000000000..cef0f1ea3 --- /dev/null +++ b/test_regress/t/t_savable_timing_bad.out @@ -0,0 +1,2 @@ +%Error: Unsupported: --timing and --savable not supported together +%Error: Exiting due to diff --git a/test_regress/t/t_savable_timing_bad.py b/test_regress/t/t_savable_timing_bad.py new file mode 100755 index 000000000..31065f1eb --- /dev/null +++ b/test_regress/t/t_savable_timing_bad.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t/t_savable_coverage_bad.v" + +test.compile(v_flags2=["--savable --timing"], + save_time=500, + fails=True, + expect_filename=test.golden_filename) + +test.passes() From 8a121803f5226d2c49c8a3562216aff73670e88d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 19 Dec 2024 20:56:47 -0500 Subject: [PATCH 163/171] Add configure CFG_CXX_VERSION --- configure.ac | 6 ++++-- include/verilated.mk.in | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 1f0897f7f..83b5ea21b 100644 --- a/configure.ac +++ b/configure.ac @@ -176,8 +176,10 @@ AC_PROG_CXX AC_PROG_INSTALL AC_LANG_PUSH(C++) -cxx_version=$($CXX --version | head -1) -AC_MSG_RESULT([compiler is $CXX --version = $cxx_version]) +CFG_CXX_VERSION=`$CXX --version | head -1` +AC_MSG_RESULT([compiler $CXX --version = $CFG_CXX_VERSION]) +AC_SUBST(CFG_CXX_VERSION) + AC_MSG_CHECKING([that C++ compiler can compile simple program]) AC_RUN_IFELSE( [AC_LANG_SOURCE([int main() { return 0; }])], diff --git a/include/verilated.mk.in b/include/verilated.mk.in index a38afe987..a99873f15 100644 --- a/include/verilated.mk.in +++ b/include/verilated.mk.in @@ -23,6 +23,12 @@ PYTHON3 = @PYTHON3@ CFG_WITH_CCWARN = @CFG_WITH_CCWARN@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@ +# Compiler version found during configure. This make variable is not used +# here, but note that if this differs from what `$(CXX) --version` prints, +# then there may be strange results such as unexpected warnings, as +# configure determines compiler characteristics. +CFG_CXX_VERSION = "@CFG_CXX_VERSION@" + # Compiler flags to enable profiling CFG_CXXFLAGS_PROFILE = @CFG_CXXFLAGS_PROFILE@ # Select language required to compile (often empty) From 9a3dcaa10b7ad06e5f99e3c001f43a7325cac8ee Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 19 Dec 2024 21:30:14 -0500 Subject: [PATCH 164/171] Fix spelling --- src/V3DfgPeephole.cpp | 2 +- src/V3LinkLValue.cpp | 2 +- src/V3Width.cpp | 2 +- test_regress/t/t_param_store_bad.out | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index 531d5c35b..da61dc855 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -152,7 +152,7 @@ class V3DfgPeephole final : public DfgVisitor { // METHODS bool checkApplying(VDfgPeepholePattern id) { if (!m_ctx.m_enabled[id]) return false; - UINFO(9, "Applying DFG patten " << id.ascii() << endl); + UINFO(9, "Applying DFG pattern " << id.ascii() << endl); ++m_ctx.m_count[id]; return true; } diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 160d0075e..0d55dff70 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -53,7 +53,7 @@ class LinkLValueVisitor final : public VNVisitor { // as V3LinkLValue runs after V3Param nodep->v3error("Storing to parameter variable " << nodep->prettyNameQ() - << " in a context that is determed only at runtime"); + << " in a context that is determined only at runtime"); } if (m_setContinuously) { nodep->varp()->isContinuously(true); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 59c64c97a..798d4e34e 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -672,7 +672,7 @@ class WidthVisitor final : public VNVisitor { void visit(AstDefaultDisable* nodep) override { assertAtStatement(nodep); // it's like an if() condition. - iterateCheckBool(nodep, "default disable iff condiftion", nodep->condp(), BOTH); + iterateCheckBool(nodep, "default disable iff condition", nodep->condp(), BOTH); } void visit(AstDelay* nodep) override { if (VN_IS(m_procedurep, Final)) { diff --git a/test_regress/t/t_param_store_bad.out b/test_regress/t/t_param_store_bad.out index 7a47a6e14..8db0b471b 100644 --- a/test_regress/t/t_param_store_bad.out +++ b/test_regress/t/t_param_store_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_param_store_bad.v:12:31: Storing to parameter variable 'S' in a context that is determed only at runtime +%Error: t/t_param_store_bad.v:12:31: Storing to parameter variable 'S' in a context that is determined only at runtime 12 | $value$plusargs("S=%s", S); | ^ %Error: Exiting due to From 530ebecfb727fc64b5211a31e1dd3a9e890684c3 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 19 Dec 2024 21:42:52 -0500 Subject: [PATCH 165/171] Tests: Add module-in-module coverage --- test_regress/t/t_dist_warn_coverage.py | 13 ------------- test_regress/t/t_mod_mod.out | 17 +++++++++++++++++ test_regress/t/t_mod_mod.py | 16 ++++++++++++++++ test_regress/t/t_mod_mod.v | 21 +++++++++++++++++++++ 4 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 test_regress/t/t_mod_mod.out create mode 100755 test_regress/t/t_mod_mod.py create mode 100644 test_regress/t/t_mod_mod.v diff --git a/test_regress/t/t_dist_warn_coverage.py b/test_regress/t/t_dist_warn_coverage.py index e953e0217..cf8133fb1 100755 --- a/test_regress/t/t_dist_warn_coverage.py +++ b/test_regress/t/t_dist_warn_coverage.py @@ -47,14 +47,12 @@ for s in [ 'Illegal +: or -: select; type already selected, or bad dimension: ', 'Illegal bit or array select; type already selected, or bad dimension: ', 'Illegal range select; type already selected, or bad dimension: ', - 'Interface port ', 'Member selection of non-struct/union object \'', 'Modport item is not a function/task: ', 'Modport item is not a variable: ', 'Modport item not found: ', 'Modport not referenced as .', 'Modport not referenced from underneath an interface: ', - 'Non-interface used as an interface: ', 'Parameter type pin value isn\'t a type: Param ', 'Parameter type variable isn\'t a type: Param ', 'Pattern replication value of 0 is not legal.', @@ -86,12 +84,9 @@ for s in [ 'Unsupported: Modport dotted port name', 'Unsupported: Modport export with prototype', 'Unsupported: Modport import with prototype', - 'Unsupported: Non-variable on LHS of built-in method \'', 'Unsupported: Only one PSL clock allowed per assertion', 'Unsupported: Per-bit array instantiations ', 'Unsupported: Public functions with >64 bit outputs; ', - 'Unsupported: RHS of ==? or !=? must be ', - 'Unsupported: Randomize \'local::\'', 'Unsupported: Replication to form ', 'Unsupported: Shifting of by over 32-bit number isn\'t supported.', 'Unsupported: Signal strengths are unsupported ', @@ -111,11 +106,6 @@ for s in [ 'Unsupported: extern interface', 'Unsupported: extern module', 'Unsupported: extern task', - 'Unsupported: interface decls within interface decls', - 'Unsupported: interface decls within module decls', - 'Unsupported: module decls within module decls', - 'Unsupported: program decls within interface decls', - 'Unsupported: program decls within module decls', 'Unsupported: property port \'local\'', 'Unsupported: randsequence production list', 'Unsupported: randsequence repeat', @@ -123,10 +113,7 @@ for s in [ 'Unsupported: s_always (in property expression)', 'Unsupported: this.super', 'Unsupported: trireg', - 'Unsupported: wand', 'Unsupported: with[] stream expression', - 'Unsupported: wor', - 'Unsupported: event arrays', 'Unsupported: modport export', 'Unsupported: no_inline for tasks', 'Unsupported: static cast to ', diff --git a/test_regress/t/t_mod_mod.out b/test_regress/t/t_mod_mod.out new file mode 100644 index 000000000..755121ab5 --- /dev/null +++ b/test_regress/t/t_mod_mod.out @@ -0,0 +1,17 @@ +%Error-UNSUPPORTED: t/t_mod_mod.v:10:3: Unsupported: module decls within module decls + 10 | program p_in_m(); + | ^~~~~~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error-UNSUPPORTED: t/t_mod_mod.v:12:3: Unsupported: program decls within module decls + 12 | interface i_in_m(); + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_mod_mod.v:14:1: Unsupported: interface decls within module decls + 14 | endmodule + | ^~~~~~~~~ +%Error-UNSUPPORTED: t/t_mod_mod.v:19:3: Unsupported: interface decls within interface decls + 19 | program p_in_i(); + | ^~~~~~~ +%Error-UNSUPPORTED: t/t_mod_mod.v:21:1: Unsupported: program decls within interface decls + 21 | endinterface + | ^~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_mod_mod.py b/test_regress/t/t_mod_mod.py new file mode 100755 index 000000000..6585af685 --- /dev/null +++ b/test_regress/t/t_mod_mod.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(fails=test.vlt_all, expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_mod_mod.v b/test_regress/t/t_mod_mod.v new file mode 100644 index 000000000..8e4465d0f --- /dev/null +++ b/test_regress/t/t_mod_mod.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2008 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module m(); + module m_in_m; + endmodule + program p_in_m(); + endprogram + interface i_in_m(); + endinterface +endmodule + +interface i(); + interface i_in_i(); + endinterface + program p_in_i(); + endprogram +endinterface From 72a47e16c124e3c0f93c16d5049e0db79764bc01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Mon, 23 Dec 2024 16:10:46 +0100 Subject: [PATCH 166/171] Fix verilator_gantt for hierarchically Verilated models (#5700) --- bin/verilator_gantt | 32 ++++++++++++--------- src/V3EmitCModel.cpp | 3 +- src/V3Order.cpp | 6 ++-- src/V3Sched.cpp | 4 ++- test_regress/t/t_gantt_hier.py | 52 ++++++++++++++++++++++++++++++++++ test_regress/t/t_gen_alw.v | 2 +- 6 files changed, 81 insertions(+), 18 deletions(-) create mode 100755 test_regress/t/t_gantt_hier.py diff --git a/bin/verilator_gantt b/bin/verilator_gantt index 40450d299..5ad1d0411 100755 --- a/bin/verilator_gantt +++ b/bin/verilator_gantt @@ -36,7 +36,7 @@ def read_data(filename): re_proc_cpu = re.compile(r'VLPROFPROC processor\s*:\s*(\d+)\s*$') re_proc_dat = re.compile(r'VLPROFPROC ([a-z_ ]+)\s*:\s*(.*)$') cpu = None - thread = None + thread = 0 execGraphStart = None global LongestVcdStrValueLength @@ -54,11 +54,11 @@ def read_data(filename): if kind == "SECTION_PUSH": LongestVcdStrValueLength = max(LongestVcdStrValueLength, len(payload)) SectionStack.append(payload) - Sections.append((tick, tuple(SectionStack))) + Sections[thread].append((tick, tuple(SectionStack))) elif kind == "SECTION_POP": assert SectionStack, "SECTION_POP without SECTION_PUSH" SectionStack.pop() - Sections.append((tick, tuple(SectionStack))) + Sections[thread].append((tick, tuple(SectionStack))) elif kind == "MTASK_BEGIN": mtask, predict_start, ecpu = re_payload_mtaskBegin.match(payload).groups() mtask = int(mtask) @@ -97,6 +97,7 @@ def read_data(filename): print("-Unknown execution trace record: %s" % line) elif re_thread.match(line): thread = int(re_thread.match(line).group(1)) + Sections.append([]) elif re.match(r'^VLPROF(THREAD|VERSION)', line): pass elif re_arg1.match(line): @@ -307,23 +308,27 @@ def report_cpus(): def report_sections(): - if not Sections: - return - print("\nSection profile:") + for thread, section in enumerate(Sections): + if section: + print(f"\nSection profile for thread {thread}:") + report_section(section) + +def report_section(section): totalTime = collections.defaultdict(lambda: 0) selfTime = collections.defaultdict(lambda: 0) sectionTree = [0, {}, 1] # [selfTime, childTrees, numberOfTimesEntered] prevTime = 0 prevStack = () - for time, stack in Sections: + for time, stack in section: if len(stack) > len(prevStack): scope = sectionTree for item in stack: scope = scope[1].setdefault(item, [0, {}, 0]) scope[2] += 1 dt = time - prevTime + assert dt >= 0 scope = sectionTree for item in prevStack: scope = scope[1].setdefault(item, [0, {}, 0]) @@ -457,12 +462,13 @@ def write_vcd(filename): addValue(pcode, time, value) # Section graph - if Sections: - scode = getCode(LongestVcdStrValueLength * 8, "section", "trace") - dcode = getCode(32, "section", "depth") - for time, stack in Sections: - addValue(scode, time, stack[-1] if stack else None) - addValue(dcode, time, len(stack)) + for thread, section in enumerate(Sections): + if section: + scode = getCode(LongestVcdStrValueLength * 8, "section", f"t{thread}_trace") + dcode = getCode(32, "section", f"t{thread}_depth") + for time, stack in section: + addValue(scode, time, stack[-1] if stack else None) + addValue(dcode, time, len(stack)) # Create output file fh.write("$version Generated by verilator_gantt $end\n") diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index d31dc8ca6..bba454557 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -432,7 +432,8 @@ class EmitCModel final : public EmitCFunc { puts(topModNameProtected + "__" + protect("_eval_settle") + "(&(vlSymsp->TOP));\n"); puts("}\n"); - if (v3Global.opt.profExec()) puts("vlSymsp->__Vm_executionProfilerp->configure();\n"); + if (v3Global.opt.profExec() && !v3Global.opt.hierChild()) + puts("vlSymsp->__Vm_executionProfilerp->configure();\n"); puts("VL_DEBUG_IF(VL_DBG_MSGF(\"+ Eval\\n\"););\n"); puts(topModNameProtected + "__" + protect("_eval") + "(&(vlSymsp->TOP));\n"); diff --git a/src/V3Order.cpp b/src/V3Order.cpp index 431a5f956..a8217afb0 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -123,8 +123,10 @@ AstCFunc* V3Order::order(AstNetlist* netlistp, // }(); if (v3Global.opt.profExec()) { - funcp->addStmtsp(new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"func " - + tag + "\");\n"}); + const string name + = (v3Global.opt.hierChild() ? (v3Global.opt.topModule() + " ") : "") + "func " + tag; + funcp->addStmtsp(new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"" + + name + "\");\n"}); } // Build the OrderGraph diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index d85cf93b8..c5af5acaa 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -156,7 +156,9 @@ AstNodeStmt* checkIterationLimit(AstNetlist* netlistp, const string& name, AstVa return ifp; } -AstNodeStmt* profExecSectionPush(FileLine* flp, const string& name) { +AstNodeStmt* profExecSectionPush(FileLine* flp, const string& section) { + const string name + = (v3Global.opt.hierChild() ? (v3Global.opt.topModule() + " ") : "") + section; return new AstCStmt{flp, "VL_EXEC_TRACE_ADD_RECORD(vlSymsp).sectionPush(\"" + name + "\");\n"}; } diff --git a/test_regress/t/t_gantt_hier.py b/test_regress/t/t_gantt_hier.py new file mode 100755 index 000000000..19d2e439c --- /dev/null +++ b/test_regress/t/t_gantt_hier.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +# Test for bin/verilator_gantt, + +import vltest_bootstrap + +test.scenarios('vlt_all') +test.top_filename = "t/t_gen_alw.v" # Any, as long as runs a few cycles + +test.compile( + v_flags2=["--prof-exec", "--hierarchical"], + # Checks below care about thread count, so use 2 (minimum reasonable) + threads=(2 if test.vltmt else 1)) + +test.execute(all_run_flags=[ + "+verilator+prof+exec+start+2", + " +verilator+prof+exec+window+2", + " +verilator+prof+exec+file+" + test.obj_dir + "/profile_exec.dat", + " +verilator+prof+vlt+file+" + test.obj_dir + "/profile.vlt"]) # yapf:disable + +# For now, verilator_gantt still reads from STDIN +# (probably it should take a file, gantt.dat like verilator_profcfunc) +# The profiling data still goes direct to the runtime's STDOUT +# (maybe that should go to a separate file - gantt.dat?) +test.run(cmd=[ + os.environ["VERILATOR_ROOT"] + "/bin/verilator_gantt", test.obj_dir + + "/profile_exec.dat", "--vcd " + test.obj_dir + "/profile_exec.vcd", "| tee " + test.obj_dir + + "/gantt.log" +]) + +if test.vltmt: + test.file_grep(test.obj_dir + "/gantt.log", r'Total threads += 2') + test.file_grep(test.obj_dir + "/gantt.log", r'Total mtasks += 8') + # Predicted thread utilization should be less than 100% + test.file_grep_not(test.obj_dir + "/gantt.log", r'Thread utilization =\s*\d\d\d+\.\d+%') +else: + test.file_grep(test.obj_dir + "/gantt.log", r'Total threads += 1') + test.file_grep(test.obj_dir + "/gantt.log", r'Total mtasks += 0') + +test.file_grep(test.obj_dir + "/gantt.log", r'\|\s+2\s+\|\s+2\.0+\s+\|\s+eval') + +# Diff to itself, just to check parsing +test.vcd_identical(test.obj_dir + "/profile_exec.vcd", test.obj_dir + "/profile_exec.vcd") + +test.passes() diff --git a/test_regress/t/t_gen_alw.v b/test_regress/t/t_gen_alw.v index 21b953839..27b86e96b 100644 --- a/test_regress/t/t_gen_alw.v +++ b/test_regress/t/t_gen_alw.v @@ -59,7 +59,7 @@ endmodule module Test (/*AUTOARG*/ // Inputs clk, in - ); + ); /*verilator hier_block*/ input clk; input [9:0] in; From 8fbb725f3489ba39e572b4412454b21290206ee8 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jan 2025 08:30:25 -0500 Subject: [PATCH 167/171] Copyright year update. --- CMakeLists.txt | 2 +- Changes | 2 +- Makefile.in | 2 +- README.rst | 2 +- bin/redirect | 2 +- bin/verilator | 4 ++-- bin/verilator_ccache_report | 2 +- bin/verilator_coverage | 4 ++-- bin/verilator_difftree | 2 +- bin/verilator_gantt | 2 +- bin/verilator_includer | 2 +- bin/verilator_profcfunc | 2 +- ci/docker/buildenv/README.rst | 2 +- ci/docker/run/README.rst | 2 +- codecov.yml | 2 +- configure.ac | 2 +- docs/Makefile | 2 +- docs/bin/vl_sphinx_extract | 2 +- docs/bin/vl_sphinx_fix | 2 +- docs/guide/changes.rst | 2 +- docs/guide/conf.py | 2 +- docs/guide/connecting.rst | 2 +- docs/guide/contributing.rst | 2 +- docs/guide/contributors.rst | 2 +- docs/guide/copyright.rst | 4 ++-- docs/guide/deprecations.rst | 2 +- docs/guide/environment.rst | 2 +- docs/guide/example_binary.rst | 2 +- docs/guide/example_cc.rst | 2 +- docs/guide/example_common_install.rst | 2 +- docs/guide/example_dist.rst | 2 +- docs/guide/example_sc.rst | 2 +- docs/guide/examples.rst | 2 +- docs/guide/exe_sim.rst | 2 +- docs/guide/exe_verilator.rst | 2 +- docs/guide/exe_verilator_coverage.rst | 2 +- docs/guide/exe_verilator_gantt.rst | 2 +- docs/guide/exe_verilator_profcfunc.rst | 2 +- docs/guide/executables.rst | 2 +- docs/guide/extensions.rst | 2 +- docs/guide/faq.rst | 2 +- docs/guide/files.rst | 2 +- docs/guide/index.rst | 2 +- docs/guide/install-cmake.rst | 2 +- docs/guide/install.rst | 2 +- docs/guide/languages.rst | 2 +- docs/guide/overview.rst | 2 +- docs/guide/simulating.rst | 2 +- docs/guide/verilating.rst | 2 +- docs/guide/warnings.rst | 2 +- docs/internals.rst | 2 +- docs/xml.rst | 2 +- include/verilated.cpp | 2 +- include/verilated.h | 2 +- include/verilated.mk.in | 2 +- include/verilated.v | 2 +- include/verilated_config.h.in | 2 +- include/verilated_cov.cpp | 2 +- include/verilated_cov.h | 2 +- include/verilated_cov_key.h | 2 +- include/verilated_dpi.cpp | 2 +- include/verilated_dpi.h | 2 +- include/verilated_fst_c.cpp | 2 +- include/verilated_fst_c.h | 2 +- include/verilated_fst_sc.cpp | 2 +- include/verilated_fst_sc.h | 2 +- include/verilated_funcs.h | 2 +- include/verilated_imp.h | 2 +- include/verilated_intrinsics.h | 2 +- include/verilated_probdist.cpp | 2 +- include/verilated_profiler.cpp | 2 +- include/verilated_profiler.h | 2 +- include/verilated_save.cpp | 2 +- include/verilated_save.h | 2 +- include/verilated_sc.h | 2 +- include/verilated_sc_trace.h | 2 +- include/verilated_std.sv | 2 +- include/verilated_std_waiver.vlt | 2 +- include/verilated_sym_props.h | 2 +- include/verilated_syms.h | 2 +- include/verilated_threads.cpp | 2 +- include/verilated_threads.h | 2 +- include/verilated_trace.h | 2 +- include/verilated_trace_imp.h | 2 +- include/verilated_types.h | 2 +- include/verilated_vcd_c.cpp | 2 +- include/verilated_vcd_c.h | 2 +- include/verilated_vcd_sc.cpp | 2 +- include/verilated_vcd_sc.h | 2 +- include/verilated_vpi.cpp | 2 +- include/verilated_vpi.h | 2 +- include/verilatedos.h | 2 +- include/verilatedos_c.h | 2 +- nodist/clang_check_attributes | 4 ++-- nodist/code_coverage | 2 +- nodist/code_coverage.dat | 2 +- nodist/dot_importer | 2 +- nodist/install_test | 2 +- nodist/lint_py_test_filter | 2 +- nodist/log_changes | 2 +- src/.gdbinit | 2 +- src/CMakeLists.txt | 2 +- src/Makefile.in | 2 +- src/Makefile_obj.in | 2 +- src/V3Active.cpp | 2 +- src/V3Active.h | 2 +- src/V3ActiveTop.cpp | 2 +- src/V3ActiveTop.h | 2 +- src/V3Assert.cpp | 2 +- src/V3Assert.h | 2 +- src/V3AssertPre.cpp | 2 +- src/V3AssertPre.h | 2 +- src/V3Ast.cpp | 2 +- src/V3Ast.h | 2 +- src/V3AstInlines.h | 2 +- src/V3AstNodeDType.h | 2 +- src/V3AstNodeExpr.h | 2 +- src/V3AstNodeOther.h | 2 +- src/V3AstNodes.cpp | 2 +- src/V3AstUserAllocator.h | 2 +- src/V3Begin.cpp | 2 +- src/V3Begin.h | 2 +- src/V3Branch.cpp | 2 +- src/V3Branch.h | 2 +- src/V3Broken.cpp | 2 +- src/V3Broken.h | 2 +- src/V3CCtors.cpp | 2 +- src/V3CCtors.h | 2 +- src/V3CUse.cpp | 2 +- src/V3CUse.h | 2 +- src/V3Case.cpp | 2 +- src/V3Case.h | 2 +- src/V3Cast.cpp | 2 +- src/V3Cast.h | 2 +- src/V3Class.cpp | 2 +- src/V3Class.h | 2 +- src/V3Clean.cpp | 2 +- src/V3Clean.h | 2 +- src/V3Clock.cpp | 2 +- src/V3Clock.h | 2 +- src/V3Combine.cpp | 2 +- src/V3Combine.h | 2 +- src/V3Common.cpp | 2 +- src/V3Common.h | 2 +- src/V3Config.cpp | 2 +- src/V3Config.h | 2 +- src/V3Const.cpp | 2 +- src/V3Const.h | 2 +- src/V3Coverage.cpp | 2 +- src/V3Coverage.h | 2 +- src/V3CoverageJoin.cpp | 2 +- src/V3CoverageJoin.h | 2 +- src/V3Dead.cpp | 2 +- src/V3Dead.h | 2 +- src/V3Delayed.cpp | 2 +- src/V3Delayed.h | 2 +- src/V3Depth.cpp | 2 +- src/V3Depth.h | 2 +- src/V3DepthBlock.cpp | 2 +- src/V3DepthBlock.h | 2 +- src/V3Descope.cpp | 2 +- src/V3Descope.h | 2 +- src/V3Dfg.cpp | 2 +- src/V3Dfg.h | 2 +- src/V3DfgAstToDfg.cpp | 2 +- src/V3DfgCache.cpp | 2 +- src/V3DfgCache.h | 2 +- src/V3DfgDecomposition.cpp | 2 +- src/V3DfgDfgToAst.cpp | 2 +- src/V3DfgOptimizer.cpp | 2 +- src/V3DfgOptimizer.h | 2 +- src/V3DfgPasses.cpp | 2 +- src/V3DfgPasses.h | 2 +- src/V3DfgPatternStats.h | 2 +- src/V3DfgPeephole.cpp | 2 +- src/V3DfgPeephole.h | 2 +- src/V3DfgRegularize.cpp | 2 +- src/V3DfgVertices.h | 2 +- src/V3DupFinder.cpp | 2 +- src/V3DupFinder.h | 2 +- src/V3EmitC.h | 2 +- src/V3EmitCBase.cpp | 2 +- src/V3EmitCBase.h | 2 +- src/V3EmitCConstInit.h | 2 +- src/V3EmitCConstPool.cpp | 2 +- src/V3EmitCFunc.cpp | 2 +- src/V3EmitCFunc.h | 2 +- src/V3EmitCHeaders.cpp | 2 +- src/V3EmitCImp.cpp | 2 +- src/V3EmitCInlines.cpp | 2 +- src/V3EmitCMain.cpp | 2 +- src/V3EmitCMain.h | 2 +- src/V3EmitCMake.cpp | 2 +- src/V3EmitCMake.h | 2 +- src/V3EmitCModel.cpp | 2 +- src/V3EmitCPch.cpp | 2 +- src/V3EmitCSyms.cpp | 2 +- src/V3EmitMk.cpp | 2 +- src/V3EmitMk.h | 2 +- src/V3EmitV.cpp | 2 +- src/V3EmitV.h | 2 +- src/V3EmitXml.cpp | 2 +- src/V3EmitXml.h | 2 +- src/V3Error.cpp | 2 +- src/V3Error.h | 2 +- src/V3ExecGraph.cpp | 2 +- src/V3ExecGraph.h | 2 +- src/V3Expand.cpp | 2 +- src/V3Expand.h | 2 +- src/V3File.cpp | 2 +- src/V3File.h | 2 +- src/V3FileLine.cpp | 2 +- src/V3FileLine.h | 2 +- src/V3Force.cpp | 2 +- src/V3Force.h | 2 +- src/V3Fork.cpp | 2 +- src/V3Fork.h | 2 +- src/V3FuncOpt.cpp | 2 +- src/V3FuncOpt.h | 2 +- src/V3FunctionTraits.h | 2 +- src/V3Gate.cpp | 2 +- src/V3Gate.h | 2 +- src/V3Global.cpp | 2 +- src/V3Global.h | 2 +- src/V3Graph.cpp | 2 +- src/V3Graph.h | 2 +- src/V3GraphAcyc.cpp | 2 +- src/V3GraphAlg.cpp | 2 +- src/V3GraphAlg.h | 2 +- src/V3GraphPathChecker.cpp | 2 +- src/V3GraphPathChecker.h | 2 +- src/V3GraphStream.h | 2 +- src/V3GraphTest.cpp | 2 +- src/V3Hash.cpp | 2 +- src/V3Hash.h | 2 +- src/V3Hasher.cpp | 2 +- src/V3Hasher.h | 2 +- src/V3HierBlock.cpp | 2 +- src/V3HierBlock.h | 2 +- src/V3Inline.cpp | 2 +- src/V3Inline.h | 2 +- src/V3Inst.cpp | 2 +- src/V3Inst.h | 2 +- src/V3InstrCount.cpp | 2 +- src/V3InstrCount.h | 2 +- src/V3Interface.cpp | 2 +- src/V3Interface.h | 2 +- src/V3LangCode.h | 2 +- src/V3LanguageWords.h | 2 +- src/V3Life.cpp | 2 +- src/V3Life.h | 2 +- src/V3LifePost.cpp | 2 +- src/V3LifePost.h | 2 +- src/V3LinkCells.cpp | 2 +- src/V3LinkCells.h | 2 +- src/V3LinkDot.cpp | 2 +- src/V3LinkDot.h | 2 +- src/V3LinkInc.cpp | 2 +- src/V3LinkInc.h | 2 +- src/V3LinkJump.cpp | 2 +- src/V3LinkJump.h | 2 +- src/V3LinkLValue.cpp | 2 +- src/V3LinkLValue.h | 2 +- src/V3LinkLevel.cpp | 2 +- src/V3LinkLevel.h | 2 +- src/V3LinkParse.cpp | 2 +- src/V3LinkParse.h | 2 +- src/V3LinkResolve.cpp | 2 +- src/V3LinkResolve.h | 2 +- src/V3List.h | 2 +- src/V3Localize.cpp | 2 +- src/V3Localize.h | 2 +- src/V3MemberMap.h | 2 +- src/V3MergeCond.cpp | 2 +- src/V3MergeCond.h | 2 +- src/V3Mutex.h | 2 +- src/V3Name.cpp | 2 +- src/V3Name.h | 2 +- src/V3Number.cpp | 2 +- src/V3Number.h | 2 +- src/V3OptionParser.cpp | 2 +- src/V3OptionParser.h | 2 +- src/V3Options.cpp | 4 ++-- src/V3Options.h | 2 +- src/V3Order.cpp | 2 +- src/V3Order.h | 2 +- src/V3OrderCFuncEmitter.h | 2 +- src/V3OrderGraph.h | 2 +- src/V3OrderGraphBuilder.cpp | 2 +- src/V3OrderInternal.h | 2 +- src/V3OrderMoveGraph.cpp | 2 +- src/V3OrderMoveGraph.h | 2 +- src/V3OrderParallel.cpp | 2 +- src/V3OrderProcessDomains.cpp | 2 +- src/V3OrderSerial.cpp | 2 +- src/V3Os.cpp | 2 +- src/V3Os.h | 2 +- src/V3PairingHeap.h | 2 +- src/V3Param.cpp | 2 +- src/V3Param.h | 2 +- src/V3Parse.h | 2 +- src/V3ParseGrammar.cpp | 2 +- src/V3ParseImp.cpp | 2 +- src/V3ParseImp.h | 2 +- src/V3ParseLex.cpp | 2 +- src/V3ParseSym.h | 2 +- src/V3PchAstMT.h | 2 +- src/V3PchAstNoMT.h | 2 +- src/V3PreExpr.h | 2 +- src/V3PreLex.h | 2 +- src/V3PreLex.l | 2 +- src/V3PreProc.cpp | 2 +- src/V3PreProc.h | 2 +- src/V3PreShell.cpp | 2 +- src/V3PreShell.h | 2 +- src/V3Premit.cpp | 2 +- src/V3Premit.h | 2 +- src/V3ProtectLib.cpp | 2 +- src/V3ProtectLib.h | 2 +- src/V3Randomize.cpp | 2 +- src/V3Randomize.h | 2 +- src/V3Reloop.cpp | 2 +- src/V3Reloop.h | 2 +- src/V3Rtti.h | 2 +- src/V3Sampled.cpp | 2 +- src/V3Sampled.h | 2 +- src/V3Sched.cpp | 2 +- src/V3Sched.h | 2 +- src/V3SchedAcyclic.cpp | 2 +- src/V3SchedPartition.cpp | 2 +- src/V3SchedReplicate.cpp | 2 +- src/V3SchedTiming.cpp | 2 +- src/V3SchedVirtIface.cpp | 2 +- src/V3Scope.cpp | 2 +- src/V3Scope.h | 2 +- src/V3Scoreboard.cpp | 2 +- src/V3Scoreboard.h | 2 +- src/V3SenExprBuilder.h | 2 +- src/V3SenTree.h | 2 +- src/V3Simulate.h | 2 +- src/V3Slice.cpp | 2 +- src/V3Slice.h | 2 +- src/V3Split.cpp | 2 +- src/V3Split.h | 2 +- src/V3SplitAs.cpp | 2 +- src/V3SplitAs.h | 2 +- src/V3SplitVar.cpp | 2 +- src/V3SplitVar.h | 2 +- src/V3StackCount.cpp | 2 +- src/V3StackCount.h | 2 +- src/V3Stats.cpp | 2 +- src/V3Stats.h | 2 +- src/V3StatsReport.cpp | 2 +- src/V3StdFuture.h | 2 +- src/V3String.cpp | 2 +- src/V3String.h | 2 +- src/V3Subst.cpp | 2 +- src/V3Subst.h | 2 +- src/V3SymTable.h | 2 +- src/V3TSP.cpp | 2 +- src/V3TSP.h | 2 +- src/V3Table.cpp | 2 +- src/V3Table.h | 2 +- src/V3Task.cpp | 2 +- src/V3Task.h | 2 +- src/V3ThreadPool.cpp | 2 +- src/V3ThreadPool.h | 2 +- src/V3Timing.cpp | 2 +- src/V3Timing.h | 2 +- src/V3Trace.cpp | 2 +- src/V3Trace.h | 2 +- src/V3TraceDecl.cpp | 2 +- src/V3TraceDecl.h | 2 +- src/V3Tristate.cpp | 2 +- src/V3Tristate.h | 2 +- src/V3Undriven.cpp | 2 +- src/V3Undriven.h | 2 +- src/V3UniqueNames.h | 2 +- src/V3Unknown.cpp | 2 +- src/V3Unknown.h | 2 +- src/V3Unroll.cpp | 2 +- src/V3Unroll.h | 2 +- src/V3VariableOrder.cpp | 2 +- src/V3VariableOrder.h | 2 +- src/V3Waiver.cpp | 2 +- src/V3Waiver.h | 2 +- src/V3Width.cpp | 2 +- src/V3Width.h | 2 +- src/V3WidthCommit.cpp | 2 +- src/V3WidthCommit.h | 2 +- src/V3WidthRemove.h | 2 +- src/V3WidthSel.cpp | 2 +- src/Verilator.cpp | 2 +- src/VlcBucket.h | 2 +- src/VlcMain.cpp | 4 ++-- src/VlcOptions.h | 2 +- src/VlcPoint.h | 2 +- src/VlcSource.h | 2 +- src/VlcTest.h | 2 +- src/VlcTop.cpp | 2 +- src/VlcTop.h | 2 +- src/astgen | 2 +- src/bisonpre | 2 +- src/config_build.h | 2 +- src/config_package.h.in | 2 +- src/config_rev | 2 +- src/cppcheck_filtered | 2 +- src/flexfix | 2 +- src/verilog.l | 2 +- src/verilog.y | 2 +- src/vlcovgen | 2 +- test_regress/CMakeLists.txt | 2 +- test_regress/Makefile | 2 +- test_regress/Makefile_obj | 2 +- test_regress/driver.py | 4 ++-- test_regress/t/TestCheck.h | 2 +- test_regress/t/TestSimulator.h | 2 +- test_regress/t/TestVpi.h | 2 +- verilator-config-version.cmake.in | 2 +- verilator-config.cmake.in | 2 +- 420 files changed, 427 insertions(+), 427 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24ed3117e..0edca19e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ # #***************************************************************************** # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/Changes b/Changes index df06d491b..e85dd88be 100644 --- a/Changes +++ b/Changes @@ -4929,7 +4929,7 @@ Verilator 0.0 1994-07-08 Copyright ========= -Copyright 2001-2024 by Wilson Snyder. This program is free software; you +Copyright 2001-2025 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. diff --git a/Makefile.in b/Makefile.in index ae88cbcf4..ea0310369 100644 --- a/Makefile.in +++ b/Makefile.in @@ -7,7 +7,7 @@ # #***************************************************************************** # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/README.rst b/README.rst index 56d925078..e62b6317d 100644 --- a/README.rst +++ b/README.rst @@ -141,7 +141,7 @@ Related Projects Open License ============ -Verilator is Copyright 2003-2024 by Wilson Snyder. (Report bugs to +Verilator is Copyright 2003-2025 by Wilson Snyder. (Report bugs to `Verilator Issues `_.) Verilator is free software; you can redistribute it and/or modify it under diff --git a/bin/redirect b/bin/redirect index 0e7becf25..ddd8c1a4d 100644 --- a/bin/redirect +++ b/bin/redirect @@ -1,7 +1,7 @@ #!/usr/bin/env perl ###################################################################### # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/bin/verilator b/bin/verilator index 4ebb3ddd9..6f8f5ae35 100755 --- a/bin/verilator +++ b/bin/verilator @@ -1,7 +1,7 @@ #!/usr/bin/env perl ###################################################################### # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. @@ -543,7 +543,7 @@ description of these arguments. The latest version is available from L. -Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +Copyright 2003-2025 by Wilson Snyder. This program is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. diff --git a/bin/verilator_ccache_report b/bin/verilator_ccache_report index 92355a898..2c39d4f30 100755 --- a/bin/verilator_ccache_report +++ b/bin/verilator_ccache_report @@ -16,7 +16,7 @@ parser = argparse.ArgumentParser( For documentation see https://verilator.org/guide/latest/exe_verilator_ccache_report.html""", - epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2002-2025 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. diff --git a/bin/verilator_coverage b/bin/verilator_coverage index 887d7b1f0..e7f1f6be2 100755 --- a/bin/verilator_coverage +++ b/bin/verilator_coverage @@ -1,7 +1,7 @@ #!/usr/bin/env perl ###################################################################### # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. @@ -188,7 +188,7 @@ L. The latest version is available from L. -Copyright 2003-2024 by Wilson Snyder. This program is free software; you +Copyright 2003-2025 by Wilson Snyder. This program is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. diff --git a/bin/verilator_difftree b/bin/verilator_difftree index 1b77e3832..b4385509b 100755 --- a/bin/verilator_difftree +++ b/bin/verilator_difftree @@ -108,7 +108,7 @@ parser = argparse.ArgumentParser( Verilator_difftree is used for debugging Verilator tree output files. It performs a diff between two files, or all files common between two directories, ignoring irrelevant pointer differences.""", - epilog="""Copyright 2005-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2005-2025 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. diff --git a/bin/verilator_gantt b/bin/verilator_gantt index 5ad1d0411..2f5fb5ec1 100755 --- a/bin/verilator_gantt +++ b/bin/verilator_gantt @@ -529,7 +529,7 @@ Verilator_gantt creates a visual representation to help analyze Verilator For documentation see https://verilator.org/guide/latest/exe_verilator_gantt.html""", - epilog="""Copyright 2018-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2018-2025 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. diff --git a/bin/verilator_includer b/bin/verilator_includer index e704723d6..c41755823 100755 --- a/bin/verilator_includer +++ b/bin/verilator_includer @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # pylint: disable=C0114,C0209 # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 by Wilson Snyder. This program is free software; you # can redistribute it and/or modify the Verilator internals under the terms # of either the GNU Lesser General Public License Version 3 or the Perl # Artistic License Version 2.0. diff --git a/bin/verilator_profcfunc b/bin/verilator_profcfunc index 51ed57a58..434fe2823 100755 --- a/bin/verilator_profcfunc +++ b/bin/verilator_profcfunc @@ -173,7 +173,7 @@ in each Verilog block. For documentation see https://verilator.org/guide/latest/exe_verilator_profcfunc.html""", - epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2002-2025 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. diff --git a/ci/docker/buildenv/README.rst b/ci/docker/buildenv/README.rst index 2f04bb732..64d82509b 100644 --- a/ci/docker/buildenv/README.rst +++ b/ci/docker/buildenv/README.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Verilator Build Docker Container: diff --git a/ci/docker/run/README.rst b/ci/docker/run/README.rst index 77cb1adf6..86bad6cdb 100644 --- a/ci/docker/run/README.rst +++ b/ci/docker/run/README.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 Verilator Executable Docker Container diff --git a/codecov.yml b/codecov.yml index bd2ee7f52..36e324e1c 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,7 +1,7 @@ --- # DESCRIPTION: codecov.io config # -# Copyright 2020-2024 by Wilson Snyder. This program is free software; you +# Copyright 2020-2025 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. diff --git a/configure.ac b/configure.ac index 83b5ea21b..cb740447c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # DESCRIPTION: Process this file with autoconf to produce a configure script. # -# Copyright 2003-2024 by Wilson Snyder. Verilator is free software; you +# Copyright 2003-2025 by Wilson Snyder. Verilator 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 diff --git a/docs/Makefile b/docs/Makefile index 78e39fae8..71b3092eb 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -5,7 +5,7 @@ # # Code available from: https://verilator.org # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/docs/bin/vl_sphinx_extract b/docs/bin/vl_sphinx_extract index 75a7585bf..99caea230 100755 --- a/docs/bin/vl_sphinx_extract +++ b/docs/bin/vl_sphinx_extract @@ -37,7 +37,7 @@ parser = argparse.ArgumentParser( allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter, description="""Read a file and extract documentation data.""", - epilog=""" Copyright 2021-2024 by Wilson Snyder. This package is free software; + epilog=""" Copyright 2021-2025 by Wilson Snyder. This package 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. diff --git a/docs/bin/vl_sphinx_fix b/docs/bin/vl_sphinx_fix index d0e607a48..185a0a55d 100755 --- a/docs/bin/vl_sphinx_fix +++ b/docs/bin/vl_sphinx_fix @@ -53,7 +53,7 @@ parser = argparse.ArgumentParser( allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter, description="""Post-process Sphinx HTML.""", - epilog=""" Copyright 2021-2024 by Wilson Snyder. This package is free software; + epilog=""" Copyright 2021-2025 by Wilson Snyder. This package 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. diff --git a/docs/guide/changes.rst b/docs/guide/changes.rst index c9f86a5c1..7454f5162 100644 --- a/docs/guide/changes.rst +++ b/docs/guide/changes.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 **************** diff --git a/docs/guide/conf.py b/docs/guide/conf.py index a01718c9e..328a4e900 100644 --- a/docs/guide/conf.py +++ b/docs/guide/conf.py @@ -1,7 +1,7 @@ # pylint: disable=C0103,C0114,C0116,C0301,E0402,W0622 # # Configuration file for Verilator's Sphinx documentation builder. -# Copyright 2003-2024 by Wilson Snyder. +# Copyright 2003-2025 by Wilson Snyder. # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 # # This file only contains overridden options. For a full list: diff --git a/docs/guide/connecting.rst b/docs/guide/connecting.rst index 724c2938b..c0f08175d 100644 --- a/docs/guide/connecting.rst +++ b/docs/guide/connecting.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Connecting: diff --git a/docs/guide/contributing.rst b/docs/guide/contributing.rst index 056a3e375..051b69869 100644 --- a/docs/guide/contributing.rst +++ b/docs/guide/contributing.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ******************************* diff --git a/docs/guide/contributors.rst b/docs/guide/contributors.rst index ff223257a..eb8b24f92 100644 --- a/docs/guide/contributors.rst +++ b/docs/guide/contributors.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ************************ diff --git a/docs/guide/copyright.rst b/docs/guide/copyright.rst index 5eb6d516c..e83fcc1ed 100644 --- a/docs/guide/copyright.rst +++ b/docs/guide/copyright.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ********* @@ -8,7 +8,7 @@ Copyright The latest version of Verilator is available from `https://verilator.org `_. -Copyright 2003-2024 by Wilson Snyder. This program is free software; you +Copyright 2003-2025 by Wilson Snyder. This program is free software; you can redistribute it and/or modify the Verilator internals under the terms of either the GNU Lesser General Public License Version 3 or the Perl Artistic License Version 2.0. diff --git a/docs/guide/deprecations.rst b/docs/guide/deprecations.rst index 7df77fcf9..130197f18 100644 --- a/docs/guide/deprecations.rst +++ b/docs/guide/deprecations.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 Deprecations diff --git a/docs/guide/environment.rst b/docs/guide/environment.rst index d099acea3..f70d35763 100644 --- a/docs/guide/environment.rst +++ b/docs/guide/environment.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 Environment diff --git a/docs/guide/example_binary.rst b/docs/guide/example_binary.rst index 43f895b9b..3085d235d 100644 --- a/docs/guide/example_binary.rst +++ b/docs/guide/example_binary.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Example Create-Binary Execution: diff --git a/docs/guide/example_cc.rst b/docs/guide/example_cc.rst index 11c7d706f..2173e64e1 100644 --- a/docs/guide/example_cc.rst +++ b/docs/guide/example_cc.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Example C++ Execution: diff --git a/docs/guide/example_common_install.rst b/docs/guide/example_common_install.rst index d7ddb0bab..ecf9f813b 100644 --- a/docs/guide/example_common_install.rst +++ b/docs/guide/example_common_install.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 First you need Verilator installed, see :ref:`Installation`. In brief, if diff --git a/docs/guide/example_dist.rst b/docs/guide/example_dist.rst index 4b15464b6..cafb63c12 100644 --- a/docs/guide/example_dist.rst +++ b/docs/guide/example_dist.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Examples in the Distribution: diff --git a/docs/guide/example_sc.rst b/docs/guide/example_sc.rst index f844f4a25..c6e235785 100644 --- a/docs/guide/example_sc.rst +++ b/docs/guide/example_sc.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Example SystemC Execution: diff --git a/docs/guide/examples.rst b/docs/guide/examples.rst index c2328b8da..7c27c6d5f 100644 --- a/docs/guide/examples.rst +++ b/docs/guide/examples.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Examples: diff --git a/docs/guide/exe_sim.rst b/docs/guide/exe_sim.rst index 7a449e3fb..743541794 100644 --- a/docs/guide/exe_sim.rst +++ b/docs/guide/exe_sim.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Simulation Runtime Arguments: diff --git a/docs/guide/exe_verilator.rst b/docs/guide/exe_verilator.rst index 7a88b6180..7afdb5df6 100644 --- a/docs/guide/exe_verilator.rst +++ b/docs/guide/exe_verilator.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 verilator Arguments diff --git a/docs/guide/exe_verilator_coverage.rst b/docs/guide/exe_verilator_coverage.rst index 4f9f1be84..c29f9d329 100644 --- a/docs/guide/exe_verilator_coverage.rst +++ b/docs/guide/exe_verilator_coverage.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 verilator_coverage diff --git a/docs/guide/exe_verilator_gantt.rst b/docs/guide/exe_verilator_gantt.rst index e1275d9c7..9916b0a87 100644 --- a/docs/guide/exe_verilator_gantt.rst +++ b/docs/guide/exe_verilator_gantt.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 verilator_gantt diff --git a/docs/guide/exe_verilator_profcfunc.rst b/docs/guide/exe_verilator_profcfunc.rst index ec2548e01..8fb7fba33 100644 --- a/docs/guide/exe_verilator_profcfunc.rst +++ b/docs/guide/exe_verilator_profcfunc.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 verilator_profcfunc diff --git a/docs/guide/executables.rst b/docs/guide/executables.rst index fee757f8a..229798083 100644 --- a/docs/guide/executables.rst +++ b/docs/guide/executables.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ********************************* diff --git a/docs/guide/extensions.rst b/docs/guide/extensions.rst index 557ddc015..292534f61 100644 --- a/docs/guide/extensions.rst +++ b/docs/guide/extensions.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ******************* diff --git a/docs/guide/faq.rst b/docs/guide/faq.rst index 12aa3eb9a..10a5cbde7 100644 --- a/docs/guide/faq.rst +++ b/docs/guide/faq.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ****************************** diff --git a/docs/guide/files.rst b/docs/guide/files.rst index a932eb7f1..9eab365b8 100644 --- a/docs/guide/files.rst +++ b/docs/guide/files.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ***** diff --git a/docs/guide/index.rst b/docs/guide/index.rst index 7d6a3f1c8..54603d249 100644 --- a/docs/guide/index.rst +++ b/docs/guide/index.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ###################### diff --git a/docs/guide/install-cmake.rst b/docs/guide/install-cmake.rst index 2120ee951..f096d769b 100644 --- a/docs/guide/install-cmake.rst +++ b/docs/guide/install-cmake.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _CMakeInstallation: diff --git a/docs/guide/install.rst b/docs/guide/install.rst index 05a58d244..c0f180d09 100644 --- a/docs/guide/install.rst +++ b/docs/guide/install.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Installation: diff --git a/docs/guide/languages.rst b/docs/guide/languages.rst index 9f32a8a03..969d1986c 100644 --- a/docs/guide/languages.rst +++ b/docs/guide/languages.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 *************** diff --git a/docs/guide/overview.rst b/docs/guide/overview.rst index 95cf9cb17..d907ad626 100644 --- a/docs/guide/overview.rst +++ b/docs/guide/overview.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ******** diff --git a/docs/guide/simulating.rst b/docs/guide/simulating.rst index 6a3484c7f..1048199b4 100644 --- a/docs/guide/simulating.rst +++ b/docs/guide/simulating.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 .. _Simulating: diff --git a/docs/guide/verilating.rst b/docs/guide/verilating.rst index 5abc3a0aa..497abf025 100644 --- a/docs/guide/verilating.rst +++ b/docs/guide/verilating.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ********** diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index 0f5f7131d..bd8fb5b40 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1,4 +1,4 @@ -.. Copyright 2003-2024 by Wilson Snyder. +.. Copyright 2003-2025 by Wilson Snyder. .. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ******************* diff --git a/docs/internals.rst b/docs/internals.rst index 39a01048e..bbc62adcb 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -2411,7 +2411,7 @@ xsim_flags / xsim_flags2 / xsim_run_flags Distribution ============ -Copyright 2008-2024 by Wilson Snyder. Verilator is free software; you can +Copyright 2008-2025 by Wilson Snyder. Verilator 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. diff --git a/docs/xml.rst b/docs/xml.rst index 76c358edf..61390030b 100644 --- a/docs/xml.rst +++ b/docs/xml.rst @@ -70,7 +70,7 @@ The XML document consists of 4 sections within the top level Distribution ============ -Copyright 2020-2024 by Wilson Snyder. Verilator is free software; you can +Copyright 2020-2025 by Wilson Snyder. Verilator 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. diff --git a/include/verilated.cpp b/include/verilated.cpp index fd80ae41a..15f3b10a9 100644 --- a/include/verilated.cpp +++ b/include/verilated.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated.h b/include/verilated.h index 02a28336e..cee813c31 100644 --- a/include/verilated.h +++ b/include/verilated.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated.mk.in b/include/verilated.mk.in index a99873f15..10bf9f100 100644 --- a/include/verilated.mk.in +++ b/include/verilated.mk.in @@ -2,7 +2,7 @@ ###################################################################### # DESCRIPTION: Makefile commands for all verilated target files # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/include/verilated.v b/include/verilated.v index a230ca814..14cf02559 100644 --- a/include/verilated.v +++ b/include/verilated.v @@ -2,7 +2,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_config.h.in b/include/verilated_config.h.in index 352dc057c..7e82b6b1f 100644 --- a/include/verilated_config.h.in +++ b/include/verilated_config.h.in @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp index 6aa1ec5eb..bf3153d72 100644 --- a/include/verilated_cov.cpp +++ b/include/verilated_cov.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_cov.h b/include/verilated_cov.h index d27b648af..0d27f76ac 100644 --- a/include/verilated_cov.h +++ b/include/verilated_cov.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_cov_key.h b/include/verilated_cov_key.h index 7f956c145..f3703838d 100644 --- a/include/verilated_cov_key.h +++ b/include/verilated_cov_key.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_dpi.cpp b/include/verilated_dpi.cpp index 76be56b5e..04a926646 100644 --- a/include/verilated_dpi.cpp +++ b/include/verilated_dpi.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2009-2025 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. diff --git a/include/verilated_dpi.h b/include/verilated_dpi.h index 56e9e7fd3..cb932510b 100644 --- a/include/verilated_dpi.h +++ b/include/verilated_dpi.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_fst_c.cpp b/include/verilated_fst_c.cpp index 348ffa001..19f29f7b5 100644 --- a/include/verilated_fst_c.cpp +++ b/include/verilated_fst_c.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_fst_c.h b/include/verilated_fst_c.h index 891bf0fc2..8506d3886 100644 --- a/include/verilated_fst_c.h +++ b/include/verilated_fst_c.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_fst_sc.cpp b/include/verilated_fst_sc.cpp index 5d375e5c8..3ba722492 100644 --- a/include/verilated_fst_sc.cpp +++ b/include/verilated_fst_sc.cpp @@ -3,7 +3,7 @@ // // THIS MODULE IS PUBLICLY LICENSED // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_fst_sc.h b/include/verilated_fst_sc.h index 4cda7e548..fb8f008af 100644 --- a/include/verilated_fst_sc.h +++ b/include/verilated_fst_sc.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2001-2025 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. diff --git a/include/verilated_funcs.h b/include/verilated_funcs.h index 8aa30e0db..3e3b6af9a 100644 --- a/include/verilated_funcs.h +++ b/include/verilated_funcs.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_imp.h b/include/verilated_imp.h index c3e369e17..cdc801b53 100644 --- a/include/verilated_imp.h +++ b/include/verilated_imp.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2009-2025 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. diff --git a/include/verilated_intrinsics.h b/include/verilated_intrinsics.h index ff5f56fbd..691281783 100644 --- a/include/verilated_intrinsics.h +++ b/include/verilated_intrinsics.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_probdist.cpp b/include/verilated_probdist.cpp index 8cf9ea573..43c436a59 100644 --- a/include/verilated_probdist.cpp +++ b/include/verilated_probdist.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_profiler.cpp b/include/verilated_profiler.cpp index 4f19fc8c0..a07713112 100644 --- a/include/verilated_profiler.cpp +++ b/include/verilated_profiler.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2012-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2012-2025 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. diff --git a/include/verilated_profiler.h b/include/verilated_profiler.h index 08210df56..b8bb7e50d 100644 --- a/include/verilated_profiler.h +++ b/include/verilated_profiler.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2012-2024 by Wilson Snyder. This program is free software; you +// Copyright 2012-2025 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. diff --git a/include/verilated_save.cpp b/include/verilated_save.cpp index c2c8e3cdd..b866de572 100644 --- a/include/verilated_save.cpp +++ b/include/verilated_save.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_save.h b/include/verilated_save.h index 724fe8298..e49eaeb6d 100644 --- a/include/verilated_save.h +++ b/include/verilated_save.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2000-2024 by Wilson Snyder. This program is free software; you +// Copyright 2000-2025 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. diff --git a/include/verilated_sc.h b/include/verilated_sc.h index 3f7b901b4..2fcfb593d 100644 --- a/include/verilated_sc.h +++ b/include/verilated_sc.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2009-2025 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. diff --git a/include/verilated_sc_trace.h b/include/verilated_sc_trace.h index f9a25a75c..99bffa19f 100644 --- a/include/verilated_sc_trace.h +++ b/include/verilated_sc_trace.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2001-2025 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. diff --git a/include/verilated_std.sv b/include/verilated_std.sv index dfe8b9ab6..4ef8df547 100644 --- a/include/verilated_std.sv +++ b/include/verilated_std.sv @@ -4,7 +4,7 @@ // //************************************************************************* // -// Copyright 2022-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2022-2025 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 diff --git a/include/verilated_std_waiver.vlt b/include/verilated_std_waiver.vlt index 7a4bd9b6e..9d4e1534a 100644 --- a/include/verilated_std_waiver.vlt +++ b/include/verilated_std_waiver.vlt @@ -4,7 +4,7 @@ // //************************************************************************* // -// Copyright 2022-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2022-2025 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 diff --git a/include/verilated_sym_props.h b/include/verilated_sym_props.h index 2e7cdf805..5298787b0 100644 --- a/include/verilated_sym_props.h +++ b/include/verilated_sym_props.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_syms.h b/include/verilated_syms.h index f4eccb301..39fbaa71a 100644 --- a/include/verilated_syms.h +++ b/include/verilated_syms.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_threads.cpp b/include/verilated_threads.cpp index 45318f518..4c048e04e 100644 --- a/include/verilated_threads.cpp +++ b/include/verilated_threads.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2012-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2012-2025 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. diff --git a/include/verilated_threads.h b/include/verilated_threads.h index 48a927789..b0e40d3b5 100644 --- a/include/verilated_threads.h +++ b/include/verilated_threads.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2012-2024 by Wilson Snyder. This program is free software; you +// Copyright 2012-2025 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. diff --git a/include/verilated_trace.h b/include/verilated_trace.h index d5b8f76bb..a297087c6 100644 --- a/include/verilated_trace.h +++ b/include/verilated_trace.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_trace_imp.h b/include/verilated_trace_imp.h index ba5bd22e2..d13f5bcf6 100644 --- a/include/verilated_trace_imp.h +++ b/include/verilated_trace_imp.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_types.h b/include/verilated_types.h index a7a72d5e1..84caafa27 100644 --- a/include/verilated_types.h +++ b/include/verilated_types.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp index 9d45ae541..0a523ac0d 100644 --- a/include/verilated_vcd_c.cpp +++ b/include/verilated_vcd_c.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_vcd_c.h b/include/verilated_vcd_c.h index fffb4fab3..2ff710c9a 100644 --- a/include/verilated_vcd_c.h +++ b/include/verilated_vcd_c.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_vcd_sc.cpp b/include/verilated_vcd_sc.cpp index 0e745e4e3..56c8d6c01 100644 --- a/include/verilated_vcd_sc.cpp +++ b/include/verilated_vcd_sc.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you +// Copyright 2001-2025 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. diff --git a/include/verilated_vcd_sc.h b/include/verilated_vcd_sc.h index 397a75db1..859be41f4 100644 --- a/include/verilated_vcd_sc.h +++ b/include/verilated_vcd_sc.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //============================================================================= // -// Copyright 2001-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2001-2025 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. diff --git a/include/verilated_vpi.cpp b/include/verilated_vpi.cpp index 2f8556530..6d3a3eaf7 100644 --- a/include/verilated_vpi.cpp +++ b/include/verilated_vpi.cpp @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2009-2025 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. diff --git a/include/verilated_vpi.h b/include/verilated_vpi.h index 51727cb01..9bea201b9 100644 --- a/include/verilated_vpi.h +++ b/include/verilated_vpi.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2009-2025 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. diff --git a/include/verilatedos.h b/include/verilatedos.h index c96f1b022..4022ac2b0 100644 --- a/include/verilatedos.h +++ b/include/verilatedos.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/include/verilatedos_c.h b/include/verilatedos_c.h index 71f979529..be932befb 100644 --- a/include/verilatedos_c.h +++ b/include/verilatedos_c.h @@ -3,7 +3,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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. diff --git a/nodist/clang_check_attributes b/nodist/clang_check_attributes index b79c49a1a..c60f09a08 100755 --- a/nodist/clang_check_attributes +++ b/nodist/clang_check_attributes @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # pylint: disable=C0114,C0115,C0116,C0209,C0302,R0902,R0911,R0912,R0914,R0915,E1101 # -# Copyright 2022-2024 by Wilson Snyder. Verilator is free software; you +# Copyright 2022-2025 by Wilson Snyder. Verilator 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 Apache License 2.0. # SPDX-License-Identifier: LGPL-3.0-only OR Apache-2.0 @@ -1080,7 +1080,7 @@ def main(): allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter, description="""Check function annotations for correctness""", - epilog="""Copyright 2022-2024 by Wilson Snyder. Verilator is free software; + epilog="""Copyright 2022-2025 by Wilson Snyder. Verilator 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 Apache License 2.0. SPDX-License-Identifier: LGPL-3.0-only OR Apache-2.0""") diff --git a/nodist/code_coverage b/nodist/code_coverage index 2b9a59fb9..d99f1ec97 100755 --- a/nodist/code_coverage +++ b/nodist/code_coverage @@ -340,7 +340,7 @@ files. Run as: cd $VERILATOR_ROOT nodist/code_coverage""", - epilog="""Copyright 2019-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2019-2025 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. diff --git a/nodist/code_coverage.dat b/nodist/code_coverage.dat index 81a9af018..8f0c785d6 100644 --- a/nodist/code_coverage.dat +++ b/nodist/code_coverage.dat @@ -1,7 +1,7 @@ # -*- Python -*- # DESCRIPTION: Verilator: Internal C++ code lcov control file # -# Copyright 2019-2024 by Wilson Snyder. This program is free software; you +# Copyright 2019-2025 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. diff --git a/nodist/dot_importer b/nodist/dot_importer index 33dba831b..c8d335af5 100755 --- a/nodist/dot_importer +++ b/nodist/dot_importer @@ -79,7 +79,7 @@ parser = argparse.ArgumentParser( description="""dot_importer takes a graphvis .dot file and converts into .cpp file. This x.cpp file is then manually included in V3GraphTest.cpp to verify various xsub-algorithms.""", - epilog="""Copyright 2005-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2005-2025 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. diff --git a/nodist/install_test b/nodist/install_test index 8534ebf4f..e345f9474 100755 --- a/nodist/install_test +++ b/nodist/install_test @@ -114,7 +114,7 @@ parser = argparse.ArgumentParser( description="""install_test performs several make-and-install iterations to verify the Verilator kit. It isn't part of the normal "make test" due to the number of builds required.""", - epilog="""Copyright 2009-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2009-2025 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. diff --git a/nodist/lint_py_test_filter b/nodist/lint_py_test_filter index 813d11fc0..3cd1c78bf 100755 --- a/nodist/lint_py_test_filter +++ b/nodist/lint_py_test_filter @@ -41,7 +41,7 @@ parser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description="""lint_py_test_filter is used to filter pylint output for expected errors in Verilator test_regress/*.py tests.""", - epilog="""Copyright 2024-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2024-2025 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. diff --git a/nodist/log_changes b/nodist/log_changes index a6ec47276..7865c393a 100755 --- a/nodist/log_changes +++ b/nodist/log_changes @@ -101,7 +101,7 @@ parser = argparse.ArgumentParser( allow_abbrev=False, prog="log_changes", description="Create example entries for 'Changes' from parsing 'git log'", - epilog="""Copyright 2019-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2019-2025 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. diff --git a/src/.gdbinit b/src/.gdbinit index 1a6bac586..c340eb552 100644 --- a/src/.gdbinit +++ b/src/.gdbinit @@ -1,6 +1,6 @@ # DESCRIPTION: Verilator: GDB startup file with useful defines # -# Copyright 2012-2024 by Wilson Snyder. This program is free software; you +# Copyright 2012-2025 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. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d9b43d17a..480fdb52d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ # #***************************************************************************** # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/src/Makefile.in b/src/Makefile.in index 29172e1eb..daf96c38e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -7,7 +7,7 @@ # #***************************************************************************** # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in index 291bb88c9..94e828efb 100644 --- a/src/Makefile_obj.in +++ b/src/Makefile_obj.in @@ -7,7 +7,7 @@ # #***************************************************************************** # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/src/V3Active.cpp b/src/V3Active.cpp index 290f872cf..f9c419314 100644 --- a/src/V3Active.cpp +++ b/src/V3Active.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Active.h b/src/V3Active.h index 431a46e64..5f9795ff4 100644 --- a/src/V3Active.h +++ b/src/V3Active.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ActiveTop.cpp b/src/V3ActiveTop.cpp index 2ebebdb12..91248a918 100644 --- a/src/V3ActiveTop.cpp +++ b/src/V3ActiveTop.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ActiveTop.h b/src/V3ActiveTop.h index 979041114..81b14f664 100644 --- a/src/V3ActiveTop.h +++ b/src/V3ActiveTop.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 8c72aabef..85d65a561 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3Assert.h b/src/V3Assert.h index 08f6bbb5e..0591a1eb0 100644 --- a/src/V3Assert.h +++ b/src/V3Assert.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp index df9fbbe07..1df9aa2a7 100644 --- a/src/V3AssertPre.cpp +++ b/src/V3AssertPre.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3AssertPre.h b/src/V3AssertPre.h index 2a68a20d1..4b596395e 100644 --- a/src/V3AssertPre.h +++ b/src/V3AssertPre.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp index 4369b1176..c7d926a3e 100644 --- a/src/V3Ast.cpp +++ b/src/V3Ast.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Ast.h b/src/V3Ast.h index 961dd146c..7d6ddf3dc 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3AstInlines.h b/src/V3AstInlines.h index 8c5d67b49..90ebccfd8 100644 --- a/src/V3AstInlines.h +++ b/src/V3AstInlines.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3AstNodeDType.h b/src/V3AstNodeDType.h index dc0220797..83b80717f 100644 --- a/src/V3AstNodeDType.h +++ b/src/V3AstNodeDType.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 00ab118b6..13382f64b 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2003-2025 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 diff --git a/src/V3AstNodeOther.h b/src/V3AstNodeOther.h index 7dce283ac..811850d71 100644 --- a/src/V3AstNodeOther.h +++ b/src/V3AstNodeOther.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 0e1a02143..b792de2b0 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3AstUserAllocator.h b/src/V3AstUserAllocator.h index fdef7e36c..ec7e0cd0b 100644 --- a/src/V3AstUserAllocator.h +++ b/src/V3AstUserAllocator.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Begin.cpp b/src/V3Begin.cpp index 7d23f8489..4817bd0f1 100644 --- a/src/V3Begin.cpp +++ b/src/V3Begin.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Begin.h b/src/V3Begin.h index 5be8886e0..1abb06096 100644 --- a/src/V3Begin.h +++ b/src/V3Begin.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp index e26b066ee..56ee3f0b8 100644 --- a/src/V3Branch.cpp +++ b/src/V3Branch.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Branch.h b/src/V3Branch.h index 5d7f291c8..7b9cfbbca 100644 --- a/src/V3Branch.h +++ b/src/V3Branch.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Broken.cpp b/src/V3Broken.cpp index 29910f209..e1b5a73fd 100644 --- a/src/V3Broken.cpp +++ b/src/V3Broken.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Broken.h b/src/V3Broken.h index 7e8f7c099..f184f4d67 100644 --- a/src/V3Broken.h +++ b/src/V3Broken.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CCtors.cpp b/src/V3CCtors.cpp index afffc75c4..045628e6a 100644 --- a/src/V3CCtors.cpp +++ b/src/V3CCtors.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CCtors.h b/src/V3CCtors.h index aa8b84f38..fedf500d0 100644 --- a/src/V3CCtors.h +++ b/src/V3CCtors.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CUse.cpp b/src/V3CUse.cpp index d40abd5b5..1f90291c7 100644 --- a/src/V3CUse.cpp +++ b/src/V3CUse.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CUse.h b/src/V3CUse.h index 8102c823e..463c4fd69 100644 --- a/src/V3CUse.h +++ b/src/V3CUse.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Case.cpp b/src/V3Case.cpp index 403f0ac00..b00190ebd 100644 --- a/src/V3Case.cpp +++ b/src/V3Case.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Case.h b/src/V3Case.h index bc2fdac11..98ce9fe73 100644 --- a/src/V3Case.h +++ b/src/V3Case.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index 4f6897472..3cbd14b09 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Cast.h b/src/V3Cast.h index 15cee107e..668f22765 100644 --- a/src/V3Cast.h +++ b/src/V3Cast.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Class.cpp b/src/V3Class.cpp index be16c81cd..656ce3db2 100644 --- a/src/V3Class.cpp +++ b/src/V3Class.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Class.h b/src/V3Class.h index d23c4bd21..c5703879e 100644 --- a/src/V3Class.h +++ b/src/V3Class.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Clean.cpp b/src/V3Clean.cpp index 90035dc6c..ca3a16246 100644 --- a/src/V3Clean.cpp +++ b/src/V3Clean.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Clean.h b/src/V3Clean.h index f7d40f4fc..a93a4f854 100644 --- a/src/V3Clean.h +++ b/src/V3Clean.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Clock.cpp b/src/V3Clock.cpp index 4739d6982..a813f7b80 100644 --- a/src/V3Clock.cpp +++ b/src/V3Clock.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Clock.h b/src/V3Clock.h index f7fc9d31d..6ea26fede 100644 --- a/src/V3Clock.h +++ b/src/V3Clock.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Combine.cpp b/src/V3Combine.cpp index 45160d3f3..2dd9574a9 100644 --- a/src/V3Combine.cpp +++ b/src/V3Combine.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Combine.h b/src/V3Combine.h index 3f84519c8..2c2aed5c6 100644 --- a/src/V3Combine.h +++ b/src/V3Combine.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Common.cpp b/src/V3Common.cpp index abf3eb5e0..3d0f08885 100644 --- a/src/V3Common.cpp +++ b/src/V3Common.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Common.h b/src/V3Common.h index 249b985e0..17fd3b235 100644 --- a/src/V3Common.h +++ b/src/V3Common.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Config.cpp b/src/V3Config.cpp index b3e82248e..9b8d38a61 100644 --- a/src/V3Config.cpp +++ b/src/V3Config.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2010-2024 by Wilson Snyder. This program is free software; you +// Copyright 2010-2025 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. diff --git a/src/V3Config.h b/src/V3Config.h index c0516cedc..32ee079c0 100644 --- a/src/V3Config.h +++ b/src/V3Config.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2010-2024 by Wilson Snyder. This program is free software; you +// Copyright 2010-2025 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. diff --git a/src/V3Const.cpp b/src/V3Const.cpp index da37703aa..406f4c815 100644 --- a/src/V3Const.cpp +++ b/src/V3Const.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Const.h b/src/V3Const.h index 5395a7cb4..1491f7714 100644 --- a/src/V3Const.h +++ b/src/V3Const.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Coverage.cpp b/src/V3Coverage.cpp index 7f36c409f..afb674551 100644 --- a/src/V3Coverage.cpp +++ b/src/V3Coverage.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Coverage.h b/src/V3Coverage.h index a084ba3e5..8e8e9500b 100644 --- a/src/V3Coverage.h +++ b/src/V3Coverage.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CoverageJoin.cpp b/src/V3CoverageJoin.cpp index cf0e607a7..86fa0ea6a 100644 --- a/src/V3CoverageJoin.cpp +++ b/src/V3CoverageJoin.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3CoverageJoin.h b/src/V3CoverageJoin.h index 57da38d8b..0356c8f35 100644 --- a/src/V3CoverageJoin.h +++ b/src/V3CoverageJoin.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index a0303ccfb..d96a7d54c 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Dead.h b/src/V3Dead.h index 17bc01243..740af0029 100644 --- a/src/V3Dead.h +++ b/src/V3Dead.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Delayed.cpp b/src/V3Delayed.cpp index 82b0b156d..6b885b1d9 100644 --- a/src/V3Delayed.cpp +++ b/src/V3Delayed.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Delayed.h b/src/V3Delayed.h index d01e25f5c..c1b8e7ea4 100644 --- a/src/V3Delayed.h +++ b/src/V3Delayed.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index 49e386cc5..d28db344d 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Depth.h b/src/V3Depth.h index d563d2ad9..01c305f14 100644 --- a/src/V3Depth.h +++ b/src/V3Depth.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DepthBlock.cpp b/src/V3DepthBlock.cpp index 296709bb0..21b30e411 100644 --- a/src/V3DepthBlock.cpp +++ b/src/V3DepthBlock.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DepthBlock.h b/src/V3DepthBlock.h index cc1bcbfa0..9d91b4ef8 100644 --- a/src/V3DepthBlock.h +++ b/src/V3DepthBlock.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Descope.cpp b/src/V3Descope.cpp index b6ff4c07e..b4b403fc2 100644 --- a/src/V3Descope.cpp +++ b/src/V3Descope.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Descope.h b/src/V3Descope.h index f94f59d5a..d403fb75b 100644 --- a/src/V3Descope.h +++ b/src/V3Descope.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Dfg.cpp b/src/V3Dfg.cpp index 7df05cbb4..0cbc69966 100644 --- a/src/V3Dfg.cpp +++ b/src/V3Dfg.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Dfg.h b/src/V3Dfg.h index 880517370..3a6e9f154 100644 --- a/src/V3Dfg.h +++ b/src/V3Dfg.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgAstToDfg.cpp b/src/V3DfgAstToDfg.cpp index 2f941b9e5..aa5f8715e 100644 --- a/src/V3DfgAstToDfg.cpp +++ b/src/V3DfgAstToDfg.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgCache.cpp b/src/V3DfgCache.cpp index 036578e2b..f1abdda69 100644 --- a/src/V3DfgCache.cpp +++ b/src/V3DfgCache.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgCache.h b/src/V3DfgCache.h index ca43a6d3c..469130340 100644 --- a/src/V3DfgCache.h +++ b/src/V3DfgCache.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgDecomposition.cpp b/src/V3DfgDecomposition.cpp index 815b960c5..a6b540763 100644 --- a/src/V3DfgDecomposition.cpp +++ b/src/V3DfgDecomposition.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgDfgToAst.cpp b/src/V3DfgDfgToAst.cpp index 423ed6600..64a135e33 100644 --- a/src/V3DfgDfgToAst.cpp +++ b/src/V3DfgDfgToAst.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgOptimizer.cpp b/src/V3DfgOptimizer.cpp index d6c6f1f30..32aba69d2 100644 --- a/src/V3DfgOptimizer.cpp +++ b/src/V3DfgOptimizer.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgOptimizer.h b/src/V3DfgOptimizer.h index 067b5e801..d7c400f4d 100644 --- a/src/V3DfgOptimizer.h +++ b/src/V3DfgOptimizer.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgPasses.cpp b/src/V3DfgPasses.cpp index d67642e8c..cf3151720 100644 --- a/src/V3DfgPasses.cpp +++ b/src/V3DfgPasses.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgPasses.h b/src/V3DfgPasses.h index 2b1e08aa6..59eb73312 100644 --- a/src/V3DfgPasses.h +++ b/src/V3DfgPasses.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgPatternStats.h b/src/V3DfgPatternStats.h index cd511a6fc..6163c7505 100644 --- a/src/V3DfgPatternStats.h +++ b/src/V3DfgPatternStats.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgPeephole.cpp b/src/V3DfgPeephole.cpp index da61dc855..1e21ea675 100644 --- a/src/V3DfgPeephole.cpp +++ b/src/V3DfgPeephole.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgPeephole.h b/src/V3DfgPeephole.h index ff3debe57..02895dfa0 100644 --- a/src/V3DfgPeephole.h +++ b/src/V3DfgPeephole.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgRegularize.cpp b/src/V3DfgRegularize.cpp index e521a5ebe..182b891bb 100644 --- a/src/V3DfgRegularize.cpp +++ b/src/V3DfgRegularize.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DfgVertices.h b/src/V3DfgVertices.h index 44d2361ea..728327637 100644 --- a/src/V3DfgVertices.h +++ b/src/V3DfgVertices.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DupFinder.cpp b/src/V3DupFinder.cpp index af3aec54a..c2b44d93d 100644 --- a/src/V3DupFinder.cpp +++ b/src/V3DupFinder.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3DupFinder.h b/src/V3DupFinder.h index 81e59ee43..e2924447f 100644 --- a/src/V3DupFinder.h +++ b/src/V3DupFinder.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3EmitC.h b/src/V3EmitC.h index 98231dba4..1d344d9b5 100644 --- a/src/V3EmitC.h +++ b/src/V3EmitC.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCBase.cpp b/src/V3EmitCBase.cpp index 15177d6ec..547a17884 100644 --- a/src/V3EmitCBase.cpp +++ b/src/V3EmitCBase.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index f82323f63..ff2305aaf 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCConstInit.h b/src/V3EmitCConstInit.h index 7799aea97..7fb761828 100644 --- a/src/V3EmitCConstInit.h +++ b/src/V3EmitCConstInit.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCConstPool.cpp b/src/V3EmitCConstPool.cpp index c373e3160..b94dbc6aa 100644 --- a/src/V3EmitCConstPool.cpp +++ b/src/V3EmitCConstPool.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCFunc.cpp b/src/V3EmitCFunc.cpp index c601179a9..d39c8c4b0 100644 --- a/src/V3EmitCFunc.cpp +++ b/src/V3EmitCFunc.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCFunc.h b/src/V3EmitCFunc.h index a0eca3cd1..40c7e5423 100644 --- a/src/V3EmitCFunc.h +++ b/src/V3EmitCFunc.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCHeaders.cpp b/src/V3EmitCHeaders.cpp index 97268d140..5abde202e 100644 --- a/src/V3EmitCHeaders.cpp +++ b/src/V3EmitCHeaders.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCImp.cpp b/src/V3EmitCImp.cpp index 544c82d7c..ef8ec9241 100644 --- a/src/V3EmitCImp.cpp +++ b/src/V3EmitCImp.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCInlines.cpp b/src/V3EmitCInlines.cpp index 30d9f4e49..73cfec669 100644 --- a/src/V3EmitCInlines.cpp +++ b/src/V3EmitCInlines.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCMain.cpp b/src/V3EmitCMain.cpp index 10bbd8769..50c59106c 100644 --- a/src/V3EmitCMain.cpp +++ b/src/V3EmitCMain.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCMain.h b/src/V3EmitCMain.h index 683df4573..a27d5c25c 100644 --- a/src/V3EmitCMain.h +++ b/src/V3EmitCMain.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCMake.cpp b/src/V3EmitCMake.cpp index b35fc2886..6744098e8 100644 --- a/src/V3EmitCMake.cpp +++ b/src/V3EmitCMake.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3EmitCMake.h b/src/V3EmitCMake.h index cc0605b83..d62b51143 100644 --- a/src/V3EmitCMake.h +++ b/src/V3EmitCMake.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCModel.cpp b/src/V3EmitCModel.cpp index bba454557..41c1574c7 100644 --- a/src/V3EmitCModel.cpp +++ b/src/V3EmitCModel.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCPch.cpp b/src/V3EmitCPch.cpp index b5c9ff4dc..ca56694de 100644 --- a/src/V3EmitCPch.cpp +++ b/src/V3EmitCPch.cpp @@ -2,7 +2,7 @@ //************************************************************************* // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 633d2ba4a..926342257 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 3a6032921..f87463f34 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3EmitMk.h b/src/V3EmitMk.h index a9b612a01..4270fad3e 100644 --- a/src/V3EmitMk.h +++ b/src/V3EmitMk.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 861787ae8..b5da1b091 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3EmitV.h b/src/V3EmitV.h index 2d15c39d2..1da5bc2e8 100644 --- a/src/V3EmitV.h +++ b/src/V3EmitV.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp index e0b2edc6f..52cf00368 100644 --- a/src/V3EmitXml.cpp +++ b/src/V3EmitXml.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3EmitXml.h b/src/V3EmitXml.h index 04ae09ebc..1cf5e2138 100644 --- a/src/V3EmitXml.h +++ b/src/V3EmitXml.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Error.cpp b/src/V3Error.cpp index d874ed61d..23c70a013 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Error.h b/src/V3Error.h index 62cb9af52..c381ddfe7 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ExecGraph.cpp b/src/V3ExecGraph.cpp index 63649f9c8..5ccc71da5 100644 --- a/src/V3ExecGraph.cpp +++ b/src/V3ExecGraph.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ExecGraph.h b/src/V3ExecGraph.h index 9b672a780..fd4baa257 100644 --- a/src/V3ExecGraph.h +++ b/src/V3ExecGraph.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Expand.cpp b/src/V3Expand.cpp index efe51bed3..89ad6a858 100644 --- a/src/V3Expand.cpp +++ b/src/V3Expand.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Expand.h b/src/V3Expand.h index c97a273f4..e4f59b880 100644 --- a/src/V3Expand.h +++ b/src/V3Expand.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3File.cpp b/src/V3File.cpp index a597b704e..49a4e032b 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3File.h b/src/V3File.h index 2106f908e..b76dad9b1 100644 --- a/src/V3File.h +++ b/src/V3File.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index 64f62dea0..1ff188e88 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3FileLine.h b/src/V3FileLine.h index 41d4906f2..5b934416a 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Force.cpp b/src/V3Force.cpp index fc76d44a4..ee6b4dbb9 100644 --- a/src/V3Force.cpp +++ b/src/V3Force.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Force.h b/src/V3Force.h index f1c8fe315..6cbcc2b2d 100644 --- a/src/V3Force.h +++ b/src/V3Force.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Fork.cpp b/src/V3Fork.cpp index 21485ce98..848222334 100644 --- a/src/V3Fork.cpp +++ b/src/V3Fork.cpp @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Fork.h b/src/V3Fork.h index 4671d5901..3c3b2ac3b 100644 --- a/src/V3Fork.h +++ b/src/V3Fork.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3FuncOpt.cpp b/src/V3FuncOpt.cpp index 5cfea84bd..fd00bcf53 100644 --- a/src/V3FuncOpt.cpp +++ b/src/V3FuncOpt.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3FuncOpt.h b/src/V3FuncOpt.h index d6c1de2d3..75a6885f5 100644 --- a/src/V3FuncOpt.h +++ b/src/V3FuncOpt.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3FunctionTraits.h b/src/V3FunctionTraits.h index c5e1a4c16..4890210d4 100644 --- a/src/V3FunctionTraits.h +++ b/src/V3FunctionTraits.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Gate.cpp b/src/V3Gate.cpp index d5dfbaad4..abb8fff7d 100644 --- a/src/V3Gate.cpp +++ b/src/V3Gate.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Gate.h b/src/V3Gate.h index b6d3c66fe..b6e86e668 100644 --- a/src/V3Gate.h +++ b/src/V3Gate.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Global.cpp b/src/V3Global.cpp index bd61712cb..08bab7a2d 100644 --- a/src/V3Global.cpp +++ b/src/V3Global.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Global.h b/src/V3Global.h index 0b3f755b3..dcbe078ab 100644 --- a/src/V3Global.h +++ b/src/V3Global.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Graph.cpp b/src/V3Graph.cpp index b4a3adf08..c5f57f78d 100644 --- a/src/V3Graph.cpp +++ b/src/V3Graph.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Graph.h b/src/V3Graph.h index 765907947..9b357ceff 100644 --- a/src/V3Graph.h +++ b/src/V3Graph.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphAcyc.cpp b/src/V3GraphAcyc.cpp index 7397f1d3b..cf3ab8b9c 100644 --- a/src/V3GraphAcyc.cpp +++ b/src/V3GraphAcyc.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphAlg.cpp b/src/V3GraphAlg.cpp index 7eec461e1..bc0eff17f 100644 --- a/src/V3GraphAlg.cpp +++ b/src/V3GraphAlg.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphAlg.h b/src/V3GraphAlg.h index 4a5478237..c879cc34f 100644 --- a/src/V3GraphAlg.h +++ b/src/V3GraphAlg.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphPathChecker.cpp b/src/V3GraphPathChecker.cpp index 14930d378..f59d76cb4 100644 --- a/src/V3GraphPathChecker.cpp +++ b/src/V3GraphPathChecker.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphPathChecker.h b/src/V3GraphPathChecker.h index 761d45ff7..bd4765411 100644 --- a/src/V3GraphPathChecker.h +++ b/src/V3GraphPathChecker.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphStream.h b/src/V3GraphStream.h index 5ddab8087..835abd261 100644 --- a/src/V3GraphStream.h +++ b/src/V3GraphStream.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3GraphTest.cpp b/src/V3GraphTest.cpp index 75760d694..4bc98f035 100644 --- a/src/V3GraphTest.cpp +++ b/src/V3GraphTest.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Hash.cpp b/src/V3Hash.cpp index cb3d5468f..26b2052d6 100644 --- a/src/V3Hash.cpp +++ b/src/V3Hash.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Hash.h b/src/V3Hash.h index 7ca847697..d73fbae6f 100644 --- a/src/V3Hash.h +++ b/src/V3Hash.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Hasher.cpp b/src/V3Hasher.cpp index ea4d0aaa9..d1fde1ff2 100644 --- a/src/V3Hasher.cpp +++ b/src/V3Hasher.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Hasher.h b/src/V3Hasher.h index 221740b04..f862e9978 100644 --- a/src/V3Hasher.h +++ b/src/V3Hasher.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3HierBlock.cpp b/src/V3HierBlock.cpp index b9e985837..bc6c0f6fc 100644 --- a/src/V3HierBlock.cpp +++ b/src/V3HierBlock.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3HierBlock.h b/src/V3HierBlock.h index d3ac4906c..ff6e52fe3 100644 --- a/src/V3HierBlock.h +++ b/src/V3HierBlock.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index b577e2bc6..d4a267418 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Inline.h b/src/V3Inline.h index f1d0faad3..3d1adbc0c 100644 --- a/src/V3Inline.h +++ b/src/V3Inline.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index 0d69913aa..5555defd8 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Inst.h b/src/V3Inst.h index fe23c469f..98a82d78d 100644 --- a/src/V3Inst.h +++ b/src/V3Inst.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3InstrCount.cpp b/src/V3InstrCount.cpp index 71a05e976..365a67e41 100644 --- a/src/V3InstrCount.cpp +++ b/src/V3InstrCount.cpp @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3InstrCount.h b/src/V3InstrCount.h index 143721f49..be25b331b 100644 --- a/src/V3InstrCount.h +++ b/src/V3InstrCount.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Interface.cpp b/src/V3Interface.cpp index 146739525..6364ef847 100644 --- a/src/V3Interface.cpp +++ b/src/V3Interface.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Interface.h b/src/V3Interface.h index 2ff3c71a9..ad649a099 100644 --- a/src/V3Interface.h +++ b/src/V3Interface.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LangCode.h b/src/V3LangCode.h index 0de1b5678..c2e1ae390 100644 --- a/src/V3LangCode.h +++ b/src/V3LangCode.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LanguageWords.h b/src/V3LanguageWords.h index 31a33eae3..ba0f302de 100644 --- a/src/V3LanguageWords.h +++ b/src/V3LanguageWords.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3Life.cpp b/src/V3Life.cpp index 6f0dbb755..47a7468b8 100644 --- a/src/V3Life.cpp +++ b/src/V3Life.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Life.h b/src/V3Life.h index 36c6970ac..2eb6b3473 100644 --- a/src/V3Life.h +++ b/src/V3Life.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LifePost.cpp b/src/V3LifePost.cpp index 44a63688d..e2f96eb01 100644 --- a/src/V3LifePost.cpp +++ b/src/V3LifePost.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LifePost.h b/src/V3LifePost.h index 8a4552b00..161f54dae 100644 --- a/src/V3LifePost.h +++ b/src/V3LifePost.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkCells.cpp b/src/V3LinkCells.cpp index c25ed16f3..6e3d13fe3 100644 --- a/src/V3LinkCells.cpp +++ b/src/V3LinkCells.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkCells.h b/src/V3LinkCells.h index 5400ed83b..99254ef33 100644 --- a/src/V3LinkCells.h +++ b/src/V3LinkCells.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index 60f4ca3e3..c747239f4 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkDot.h b/src/V3LinkDot.h index 0231c9a64..943baceda 100644 --- a/src/V3LinkDot.h +++ b/src/V3LinkDot.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkInc.cpp b/src/V3LinkInc.cpp index fdc6aa9b5..0dd3fc3b4 100644 --- a/src/V3LinkInc.cpp +++ b/src/V3LinkInc.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkInc.h b/src/V3LinkInc.h index 920f77c1d..7a2015ac8 100644 --- a/src/V3LinkInc.h +++ b/src/V3LinkInc.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkJump.cpp b/src/V3LinkJump.cpp index 693d9da11..a69053115 100644 --- a/src/V3LinkJump.cpp +++ b/src/V3LinkJump.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkJump.h b/src/V3LinkJump.h index 72a7b7f71..3d73d5df8 100644 --- a/src/V3LinkJump.h +++ b/src/V3LinkJump.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkLValue.cpp b/src/V3LinkLValue.cpp index 0d55dff70..7bdd6b9b5 100644 --- a/src/V3LinkLValue.cpp +++ b/src/V3LinkLValue.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkLValue.h b/src/V3LinkLValue.h index 99cf582a1..bc9d2acb5 100644 --- a/src/V3LinkLValue.h +++ b/src/V3LinkLValue.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp index 228b9a7de..b982dbbe0 100644 --- a/src/V3LinkLevel.cpp +++ b/src/V3LinkLevel.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkLevel.h b/src/V3LinkLevel.h index dd98ffa2b..b929eb6a9 100644 --- a/src/V3LinkLevel.h +++ b/src/V3LinkLevel.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkParse.cpp b/src/V3LinkParse.cpp index 07ea7cc14..ebd9c98f1 100644 --- a/src/V3LinkParse.cpp +++ b/src/V3LinkParse.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkParse.h b/src/V3LinkParse.h index 12b2f2c11..3c1c72702 100644 --- a/src/V3LinkParse.h +++ b/src/V3LinkParse.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index ed77ba41e..cb268fa1e 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3LinkResolve.h b/src/V3LinkResolve.h index c84219fb7..cfb849067 100644 --- a/src/V3LinkResolve.h +++ b/src/V3LinkResolve.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3List.h b/src/V3List.h index 99c435f9c..89d6d36b3 100644 --- a/src/V3List.h +++ b/src/V3List.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Localize.cpp b/src/V3Localize.cpp index 64692fbd4..5a1014a62 100644 --- a/src/V3Localize.cpp +++ b/src/V3Localize.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Localize.h b/src/V3Localize.h index 456b90706..12facd1c6 100644 --- a/src/V3Localize.h +++ b/src/V3Localize.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3MemberMap.h b/src/V3MemberMap.h index 9b9035133..5053c6e35 100644 --- a/src/V3MemberMap.h +++ b/src/V3MemberMap.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3MergeCond.cpp b/src/V3MergeCond.cpp index 6bd1ea098..538bbbb28 100644 --- a/src/V3MergeCond.cpp +++ b/src/V3MergeCond.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3MergeCond.h b/src/V3MergeCond.h index 1b78dab0f..9607f398a 100644 --- a/src/V3MergeCond.h +++ b/src/V3MergeCond.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Mutex.h b/src/V3Mutex.h index 77496d752..892a596c3 100644 --- a/src/V3Mutex.h +++ b/src/V3Mutex.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2005-2025 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. diff --git a/src/V3Name.cpp b/src/V3Name.cpp index 91c67b98b..bce4a577c 100644 --- a/src/V3Name.cpp +++ b/src/V3Name.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Name.h b/src/V3Name.h index 514e6e12f..81d2d6ffe 100644 --- a/src/V3Name.h +++ b/src/V3Name.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Number.cpp b/src/V3Number.cpp index 7f02d7b1e..cb5fc9bd4 100644 --- a/src/V3Number.cpp +++ b/src/V3Number.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Number.h b/src/V3Number.h index 19b449ca3..a18c59f81 100644 --- a/src/V3Number.h +++ b/src/V3Number.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OptionParser.cpp b/src/V3OptionParser.cpp index 917cd4e9d..701c0219e 100644 --- a/src/V3OptionParser.cpp +++ b/src/V3OptionParser.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OptionParser.h b/src/V3OptionParser.h index d6160081b..b7bcc60b9 100644 --- a/src/V3OptionParser.h +++ b/src/V3OptionParser.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Options.cpp b/src/V3Options.cpp index 717328b6d..7a7714b1e 100644 --- a/src/V3Options.cpp +++ b/src/V3Options.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. @@ -2002,7 +2002,7 @@ void V3Options::showVersion(bool verbose) { if (!verbose) return; cout << "\n"; - cout << "Copyright 2003-2024 by Wilson Snyder. Verilator is free software; you can\n"; + cout << "Copyright 2003-2025 by Wilson Snyder. Verilator is free software; you can\n"; cout << "redistribute it and/or modify the Verilator internals under the terms of\n"; cout << "either the GNU Lesser General Public License Version 3 or the Perl Artistic\n"; cout << "License Version 2.0.\n"; diff --git a/src/V3Options.h b/src/V3Options.h index e1486aeda..eb3d14194 100644 --- a/src/V3Options.h +++ b/src/V3Options.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Order.cpp b/src/V3Order.cpp index a8217afb0..fcc1e859a 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Order.h b/src/V3Order.h index cf4c117e2..d3b27a7d4 100644 --- a/src/V3Order.h +++ b/src/V3Order.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderCFuncEmitter.h b/src/V3OrderCFuncEmitter.h index 37cda41f3..03752a509 100644 --- a/src/V3OrderCFuncEmitter.h +++ b/src/V3OrderCFuncEmitter.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderGraph.h b/src/V3OrderGraph.h index 7b08f4c62..697aa2fe3 100644 --- a/src/V3OrderGraph.h +++ b/src/V3OrderGraph.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderGraphBuilder.cpp b/src/V3OrderGraphBuilder.cpp index d885a399c..3dfe3c321 100644 --- a/src/V3OrderGraphBuilder.cpp +++ b/src/V3OrderGraphBuilder.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderInternal.h b/src/V3OrderInternal.h index 10bb446f4..93c25c210 100644 --- a/src/V3OrderInternal.h +++ b/src/V3OrderInternal.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderMoveGraph.cpp b/src/V3OrderMoveGraph.cpp index 6907e2263..af04e45f0 100644 --- a/src/V3OrderMoveGraph.cpp +++ b/src/V3OrderMoveGraph.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderMoveGraph.h b/src/V3OrderMoveGraph.h index 6d4b346c6..bab6ac630 100644 --- a/src/V3OrderMoveGraph.h +++ b/src/V3OrderMoveGraph.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderParallel.cpp b/src/V3OrderParallel.cpp index ffb9ff1da..67fe62bd3 100644 --- a/src/V3OrderParallel.cpp +++ b/src/V3OrderParallel.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderProcessDomains.cpp b/src/V3OrderProcessDomains.cpp index 7a27593fb..bb028342f 100644 --- a/src/V3OrderProcessDomains.cpp +++ b/src/V3OrderProcessDomains.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3OrderSerial.cpp b/src/V3OrderSerial.cpp index 1627b78f7..a23280d8a 100644 --- a/src/V3OrderSerial.cpp +++ b/src/V3OrderSerial.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Os.cpp b/src/V3Os.cpp index b11f92e61..cd38daf44 100644 --- a/src/V3Os.cpp +++ b/src/V3Os.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Os.h b/src/V3Os.h index 5974dc18b..115d01971 100644 --- a/src/V3Os.h +++ b/src/V3Os.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3PairingHeap.h b/src/V3PairingHeap.h index 32c451f9c..98b22b1e6 100644 --- a/src/V3PairingHeap.h +++ b/src/V3PairingHeap.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 0d6a3c6ca..17ecb785b 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Param.h b/src/V3Param.h index 0d0c832d0..f730628a7 100644 --- a/src/V3Param.h +++ b/src/V3Param.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Parse.h b/src/V3Parse.h index 767467702..58f318bfa 100644 --- a/src/V3Parse.h +++ b/src/V3Parse.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 481965f22..0d0cbd5c6 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index 451e08982..c2cc2cf6f 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 1afbf98fe..916bdb48c 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you +// Copyright 2009-2025 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. diff --git a/src/V3ParseLex.cpp b/src/V3ParseLex.cpp index 552d3b652..a4709ec5f 100644 --- a/src/V3ParseLex.cpp +++ b/src/V3ParseLex.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h index 9342c2b8a..1f24cd76c 100644 --- a/src/V3ParseSym.h +++ b/src/V3ParseSym.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2009-2024 by Wilson Snyder. This program is free software; you +// Copyright 2009-2025 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. diff --git a/src/V3PchAstMT.h b/src/V3PchAstMT.h index 552c0f452..8e5aaf470 100644 --- a/src/V3PchAstMT.h +++ b/src/V3PchAstMT.h @@ -2,7 +2,7 @@ //************************************************************************* // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3PchAstNoMT.h b/src/V3PchAstNoMT.h index 0971316ce..0b67f4306 100644 --- a/src/V3PchAstNoMT.h +++ b/src/V3PchAstNoMT.h @@ -2,7 +2,7 @@ //************************************************************************* // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3PreExpr.h b/src/V3PreExpr.h index 18d69cb12..b89746c15 100644 --- a/src/V3PreExpr.h +++ b/src/V3PreExpr.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2000-2023 by Wilson Snyder. This program is free software; you +// Copyright 2000-2025 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. diff --git a/src/V3PreLex.h b/src/V3PreLex.h index 7d11a9e3f..5a7cd8acf 100644 --- a/src/V3PreLex.h +++ b/src/V3PreLex.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2000-2024 by Wilson Snyder. This program is free software; you +// Copyright 2000-2025 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. diff --git a/src/V3PreLex.l b/src/V3PreLex.l index fa605d72a..7f71af112 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -5,7 +5,7 @@ * ************************************************************************** * - * Copyright 2003-2024 by Wilson Snyder. This program is free software; you + * Copyright 2003-2025 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. diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index c2cb514b3..63894e72a 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2000-2024 by Wilson Snyder. This program is free software; you +// Copyright 2000-2025 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. diff --git a/src/V3PreProc.h b/src/V3PreProc.h index 2560ce9bd..da6c0d8d8 100644 --- a/src/V3PreProc.h +++ b/src/V3PreProc.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2000-2024 by Wilson Snyder. This program is free software; you +// Copyright 2000-2025 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. diff --git a/src/V3PreShell.cpp b/src/V3PreShell.cpp index 2b02b658d..6655c0786 100644 --- a/src/V3PreShell.cpp +++ b/src/V3PreShell.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3PreShell.h b/src/V3PreShell.h index 7c15e43fd..7e8f73e90 100644 --- a/src/V3PreShell.h +++ b/src/V3PreShell.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index 14106e86b..6fb3bc8c5 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Premit.h b/src/V3Premit.h index 82388168f..5be58992d 100644 --- a/src/V3Premit.h +++ b/src/V3Premit.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ProtectLib.cpp b/src/V3ProtectLib.cpp index 7335379f7..ec66dba2d 100644 --- a/src/V3ProtectLib.cpp +++ b/src/V3ProtectLib.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ProtectLib.h b/src/V3ProtectLib.h index 4d4cfe04e..f9ecfaa5b 100644 --- a/src/V3ProtectLib.h +++ b/src/V3ProtectLib.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 15cfccf47..96c3f6945 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Randomize.h b/src/V3Randomize.h index 896c14895..f37b6a7fe 100644 --- a/src/V3Randomize.h +++ b/src/V3Randomize.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Reloop.cpp b/src/V3Reloop.cpp index 4d61ba20b..fc0f69f30 100644 --- a/src/V3Reloop.cpp +++ b/src/V3Reloop.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Reloop.h b/src/V3Reloop.h index 756de4dd7..1324e10c7 100644 --- a/src/V3Reloop.h +++ b/src/V3Reloop.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Rtti.h b/src/V3Rtti.h index e671a4d50..627310e02 100644 --- a/src/V3Rtti.h +++ b/src/V3Rtti.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Sampled.cpp b/src/V3Sampled.cpp index e933ba869..8058fa683 100644 --- a/src/V3Sampled.cpp +++ b/src/V3Sampled.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Sampled.h b/src/V3Sampled.h index bd24873e3..766b747e8 100644 --- a/src/V3Sampled.h +++ b/src/V3Sampled.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Sched.cpp b/src/V3Sched.cpp index c5af5acaa..61a7f21d1 100644 --- a/src/V3Sched.cpp +++ b/src/V3Sched.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Sched.h b/src/V3Sched.h index 6e0dd505d..4c430919b 100644 --- a/src/V3Sched.h +++ b/src/V3Sched.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SchedAcyclic.cpp b/src/V3SchedAcyclic.cpp index 05ef424a5..a1dbcaffc 100644 --- a/src/V3SchedAcyclic.cpp +++ b/src/V3SchedAcyclic.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SchedPartition.cpp b/src/V3SchedPartition.cpp index caf64561e..8da831672 100644 --- a/src/V3SchedPartition.cpp +++ b/src/V3SchedPartition.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SchedReplicate.cpp b/src/V3SchedReplicate.cpp index 172dbc3ff..fbe68e266 100644 --- a/src/V3SchedReplicate.cpp +++ b/src/V3SchedReplicate.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SchedTiming.cpp b/src/V3SchedTiming.cpp index 7e46ca8ec..b86ef9320 100644 --- a/src/V3SchedTiming.cpp +++ b/src/V3SchedTiming.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SchedVirtIface.cpp b/src/V3SchedVirtIface.cpp index a49aec90b..6fa88ee37 100644 --- a/src/V3SchedVirtIface.cpp +++ b/src/V3SchedVirtIface.cpp @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Scope.cpp b/src/V3Scope.cpp index bc71b549a..f295d478a 100644 --- a/src/V3Scope.cpp +++ b/src/V3Scope.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Scope.h b/src/V3Scope.h index c7b18e01c..d93c5256b 100644 --- a/src/V3Scope.h +++ b/src/V3Scope.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Scoreboard.cpp b/src/V3Scoreboard.cpp index 0628d05d6..c0f72da01 100644 --- a/src/V3Scoreboard.cpp +++ b/src/V3Scoreboard.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Scoreboard.h b/src/V3Scoreboard.h index 34656a4ff..548abdaab 100644 --- a/src/V3Scoreboard.h +++ b/src/V3Scoreboard.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SenExprBuilder.h b/src/V3SenExprBuilder.h index 4ce5f5f86..f837a960c 100644 --- a/src/V3SenExprBuilder.h +++ b/src/V3SenExprBuilder.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SenTree.h b/src/V3SenTree.h index f78370e00..77ff33514 100644 --- a/src/V3SenTree.h +++ b/src/V3SenTree.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Simulate.h b/src/V3Simulate.h index 1a96ca74d..4e727cd21 100644 --- a/src/V3Simulate.h +++ b/src/V3Simulate.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index c9f6238a5..ab5fdea73 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Slice.h b/src/V3Slice.h index 14d2a8de0..b22bc37ee 100644 --- a/src/V3Slice.h +++ b/src/V3Slice.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Split.cpp b/src/V3Split.cpp index 76c531644..fe0b48d89 100644 --- a/src/V3Split.cpp +++ b/src/V3Split.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Split.h b/src/V3Split.h index d0ef26847..d5de1edd4 100644 --- a/src/V3Split.h +++ b/src/V3Split.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SplitAs.cpp b/src/V3SplitAs.cpp index 145e81a39..e0de302db 100644 --- a/src/V3SplitAs.cpp +++ b/src/V3SplitAs.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SplitAs.h b/src/V3SplitAs.h index 3fe08466a..830a65567 100644 --- a/src/V3SplitAs.h +++ b/src/V3SplitAs.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SplitVar.cpp b/src/V3SplitVar.cpp index ad1be879b..26b2cd208 100644 --- a/src/V3SplitVar.cpp +++ b/src/V3SplitVar.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SplitVar.h b/src/V3SplitVar.h index 32128ebb6..6a3e25088 100644 --- a/src/V3SplitVar.h +++ b/src/V3SplitVar.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3StackCount.cpp b/src/V3StackCount.cpp index 19850cd27..23202acf9 100644 --- a/src/V3StackCount.cpp +++ b/src/V3StackCount.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3StackCount.h b/src/V3StackCount.h index 468a0d952..dad765c65 100644 --- a/src/V3StackCount.h +++ b/src/V3StackCount.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp index 0212d2816..76fdb92c6 100644 --- a/src/V3Stats.cpp +++ b/src/V3Stats.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3Stats.h b/src/V3Stats.h index a516df343..5ca56cc29 100644 --- a/src/V3Stats.h +++ b/src/V3Stats.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3StatsReport.cpp b/src/V3StatsReport.cpp index 5aa2aa159..ec62aa3da 100644 --- a/src/V3StatsReport.cpp +++ b/src/V3StatsReport.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3StdFuture.h b/src/V3StdFuture.h index 0ab865b06..67736d885 100644 --- a/src/V3StdFuture.h +++ b/src/V3StdFuture.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3String.cpp b/src/V3String.cpp index c0f8f036d..61e180c16 100644 --- a/src/V3String.cpp +++ b/src/V3String.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3String.h b/src/V3String.h index 84b89a422..db21577bd 100644 --- a/src/V3String.h +++ b/src/V3String.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp index 5b68583a9..049258a17 100644 --- a/src/V3Subst.cpp +++ b/src/V3Subst.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Subst.h b/src/V3Subst.h index edf07151f..1e4b174da 100644 --- a/src/V3Subst.h +++ b/src/V3Subst.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3SymTable.h b/src/V3SymTable.h index cc6940fe4..984df3d09 100644 --- a/src/V3SymTable.h +++ b/src/V3SymTable.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3TSP.cpp b/src/V3TSP.cpp index e027db84d..95b71a0ac 100644 --- a/src/V3TSP.cpp +++ b/src/V3TSP.cpp @@ -11,7 +11,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3TSP.h b/src/V3TSP.h index 37bfb8891..5bed130e6 100644 --- a/src/V3TSP.h +++ b/src/V3TSP.h @@ -7,7 +7,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Table.cpp b/src/V3Table.cpp index a6ac5be24..62c4d7be9 100644 --- a/src/V3Table.cpp +++ b/src/V3Table.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Table.h b/src/V3Table.h index c6d5a1123..d2cb81fa9 100644 --- a/src/V3Table.h +++ b/src/V3Table.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Task.cpp b/src/V3Task.cpp index a0aac92a6..0fe3624d3 100644 --- a/src/V3Task.cpp +++ b/src/V3Task.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Task.h b/src/V3Task.h index 5faf2aec4..af9c45a16 100644 --- a/src/V3Task.h +++ b/src/V3Task.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3ThreadPool.cpp b/src/V3ThreadPool.cpp index 576c9c86a..7730417ca 100644 --- a/src/V3ThreadPool.cpp +++ b/src/V3ThreadPool.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2005-2025 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. diff --git a/src/V3ThreadPool.h b/src/V3ThreadPool.h index a2365e6ac..0a385958a 100644 --- a/src/V3ThreadPool.h +++ b/src/V3ThreadPool.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2005-2025 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. diff --git a/src/V3Timing.cpp b/src/V3Timing.cpp index d8cc6bee9..49298d7ad 100644 --- a/src/V3Timing.cpp +++ b/src/V3Timing.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Timing.h b/src/V3Timing.h index f1704d3b1..97d5ccf0f 100644 --- a/src/V3Timing.h +++ b/src/V3Timing.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Trace.cpp b/src/V3Trace.cpp index c136a90ce..e495693f0 100644 --- a/src/V3Trace.cpp +++ b/src/V3Trace.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Trace.h b/src/V3Trace.h index 4dc831b33..73c6c9c8b 100644 --- a/src/V3Trace.h +++ b/src/V3Trace.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3TraceDecl.cpp b/src/V3TraceDecl.cpp index 181953f5f..a4a83c3d5 100644 --- a/src/V3TraceDecl.cpp +++ b/src/V3TraceDecl.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3TraceDecl.h b/src/V3TraceDecl.h index 013e625f8..39bdb9afb 100644 --- a/src/V3TraceDecl.h +++ b/src/V3TraceDecl.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 0846b085a..c8f39c26d 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Tristate.h b/src/V3Tristate.h index 791621668..98f48aaaa 100644 --- a/src/V3Tristate.h +++ b/src/V3Tristate.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Undriven.cpp b/src/V3Undriven.cpp index 483541b39..542024cfe 100644 --- a/src/V3Undriven.cpp +++ b/src/V3Undriven.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2004-2024 by Wilson Snyder. This program is free software; you +// Copyright 2004-2025 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. diff --git a/src/V3Undriven.h b/src/V3Undriven.h index 3dd1a6550..f086912fe 100644 --- a/src/V3Undriven.h +++ b/src/V3Undriven.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3UniqueNames.h b/src/V3UniqueNames.h index 92e97f154..41886942b 100644 --- a/src/V3UniqueNames.h +++ b/src/V3UniqueNames.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2005-2024 by Wilson Snyder. This program is free software; you +// Copyright 2005-2025 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. diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp index 258fa5ab1..dd2683b76 100644 --- a/src/V3Unknown.cpp +++ b/src/V3Unknown.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Unknown.h b/src/V3Unknown.h index b5967f5a1..acc68773b 100644 --- a/src/V3Unknown.h +++ b/src/V3Unknown.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Unroll.cpp b/src/V3Unroll.cpp index 6e5d55b7b..ac707874b 100644 --- a/src/V3Unroll.cpp +++ b/src/V3Unroll.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Unroll.h b/src/V3Unroll.h index f748171ca..50d51b86b 100644 --- a/src/V3Unroll.h +++ b/src/V3Unroll.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3VariableOrder.cpp b/src/V3VariableOrder.cpp index 0aad4a3d6..ea884cb17 100644 --- a/src/V3VariableOrder.cpp +++ b/src/V3VariableOrder.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3VariableOrder.h b/src/V3VariableOrder.h index 3816ca3a0..2963578a4 100644 --- a/src/V3VariableOrder.h +++ b/src/V3VariableOrder.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Waiver.cpp b/src/V3Waiver.cpp index 9c10b9c9b..c8d36bd26 100644 --- a/src/V3Waiver.cpp +++ b/src/V3Waiver.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2020-2024 by Wilson Snyder. This program is free software; you +// Copyright 2020-2025 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. diff --git a/src/V3Waiver.h b/src/V3Waiver.h index af2d415cc..1302ac1de 100644 --- a/src/V3Waiver.h +++ b/src/V3Waiver.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 798d4e34e..969209609 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3Width.h b/src/V3Width.h index f7aa836bc..88eb86c2a 100644 --- a/src/V3Width.h +++ b/src/V3Width.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3WidthCommit.cpp b/src/V3WidthCommit.cpp index e4a6e3f6c..5050fda8d 100644 --- a/src/V3WidthCommit.cpp +++ b/src/V3WidthCommit.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h index b8c963d13..c2b124f0e 100644 --- a/src/V3WidthCommit.h +++ b/src/V3WidthCommit.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3WidthRemove.h b/src/V3WidthRemove.h index 7c9a6a8a9..b879058f6 100644 --- a/src/V3WidthRemove.h +++ b/src/V3WidthRemove.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 1ebfa828a..7073cf8d4 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 1cfce8c30..002994745 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcBucket.h b/src/VlcBucket.h index 0f2697db0..203d86290 100644 --- a/src/VlcBucket.h +++ b/src/VlcBucket.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcMain.cpp b/src/VlcMain.cpp index 89b592a2d..fbabc9b07 100644 --- a/src/VlcMain.cpp +++ b/src/VlcMain.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. @@ -107,7 +107,7 @@ void VlcOptions::showVersion(bool verbose) { if (!verbose) return; std::cout << "\n"; - std::cout << "Copyright 2003-2024 by Wilson Snyder. Verilator is free software; you can\n"; + std::cout << "Copyright 2003-2025 by Wilson Snyder. Verilator is free software; you can\n"; std::cout << "redistribute it and/or modify the Verilator internals under the terms of\n"; std::cout << "either the GNU Lesser General Public License Version 3 or the Perl Artistic\n"; std::cout << "License Version 2.0.\n"; diff --git a/src/VlcOptions.h b/src/VlcOptions.h index 02671951d..edd889957 100644 --- a/src/VlcOptions.h +++ b/src/VlcOptions.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcPoint.h b/src/VlcPoint.h index d087fb528..afb546f46 100644 --- a/src/VlcPoint.h +++ b/src/VlcPoint.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcSource.h b/src/VlcSource.h index 35a99a065..8e00667a1 100644 --- a/src/VlcSource.h +++ b/src/VlcSource.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcTest.h b/src/VlcTest.h index a9ca1d8a3..32de7d662 100644 --- a/src/VlcTest.h +++ b/src/VlcTest.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp index 55a5753e7..adedf4425 100644 --- a/src/VlcTop.cpp +++ b/src/VlcTop.cpp @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/VlcTop.h b/src/VlcTop.h index d48568bd5..b0f3dc5a9 100644 --- a/src/VlcTop.h +++ b/src/VlcTop.h @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/astgen b/src/astgen index 238216720..215364a28 100755 --- a/src/astgen +++ b/src/astgen @@ -1254,7 +1254,7 @@ parser = argparse.ArgumentParser( allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter, description="""Generate V3Ast headers to reduce C++ code duplication.""", - epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2002-2025 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. diff --git a/src/bisonpre b/src/bisonpre index 8c505c312..21bffd544 100755 --- a/src/bisonpre +++ b/src/bisonpre @@ -485,7 +485,7 @@ BISON GRAMMAR EXTENSIONS If the bison version is >= the specified version, include the given command. -Copyright 2002-2024 by Wilson Snyder. This program is free software; you +Copyright 2002-2025 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. diff --git a/src/config_build.h b/src/config_build.h index e842f0444..74ebf4029 100644 --- a/src/config_build.h +++ b/src/config_build.h @@ -8,7 +8,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/config_package.h.in b/src/config_package.h.in index 663244ce3..7a7088a82 100644 --- a/src/config_package.h.in +++ b/src/config_package.h.in @@ -6,7 +6,7 @@ // // Code available from: https://verilator.org // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; +// Copyright 2003-2025 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. diff --git a/src/config_rev b/src/config_rev index bbbcf9b3f..3d187ba59 100755 --- a/src/config_rev +++ b/src/config_rev @@ -2,7 +2,7 @@ # pylint: disable=C0103,C0114 ###################################################################### # -# Copyright 2005-2024 by Wilson Snyder. This program is free software; you +# Copyright 2005-2025 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. diff --git a/src/cppcheck_filtered b/src/cppcheck_filtered index 894c1aad7..ccf633938 100755 --- a/src/cppcheck_filtered +++ b/src/cppcheck_filtered @@ -177,7 +177,7 @@ filters out unnecessary warnings related to Verilator. Run as: cd $VERILATOR_ROOT make -k cppcheck""", - epilog="""Copyright 2014-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2014-2025 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. diff --git a/src/flexfix b/src/flexfix index 13abaec70..a6479b8e1 100755 --- a/src/flexfix +++ b/src/flexfix @@ -2,7 +2,7 @@ # pylint: disable=C0114,C0301 ###################################################################### # -# Copyright 2002-2024 by Wilson Snyder. This program is free software; you +# Copyright 2002-2025 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. diff --git a/src/verilog.l b/src/verilog.l index b46bdd1bd..b1a536557 100644 --- a/src/verilog.l +++ b/src/verilog.l @@ -6,7 +6,7 @@ * ************************************************************************** * - * Copyright 2003-2024 by Wilson Snyder. Verilator is free software; you + * Copyright 2003-2025 by Wilson Snyder. Verilator 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. diff --git a/src/verilog.y b/src/verilog.y index 62eaa4815..08ac1a969 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6,7 +6,7 @@ // //************************************************************************* // -// Copyright 2003-2024 by Wilson Snyder. This program is free software; you +// Copyright 2003-2025 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. diff --git a/src/vlcovgen b/src/vlcovgen index 819556b6f..28c70e423 100755 --- a/src/vlcovgen +++ b/src/vlcovgen @@ -78,7 +78,7 @@ parser = argparse.ArgumentParser( allow_abbrev=False, formatter_class=argparse.RawDescriptionHelpFormatter, description="""Generate verilated_cov headers to reduce C++ code duplication.""", - epilog="""Copyright 2002-2024 by Wilson Snyder. This program is free software; you + epilog="""Copyright 2002-2025 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. diff --git a/test_regress/CMakeLists.txt b/test_regress/CMakeLists.txt index bc75319c7..274813b07 100644 --- a/test_regress/CMakeLists.txt +++ b/test_regress/CMakeLists.txt @@ -4,7 +4,7 @@ # # This CMake file is meant to be consumed by regression tests. # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/test_regress/Makefile b/test_regress/Makefile index 509d2624a..0ff0e757f 100644 --- a/test_regress/Makefile +++ b/test_regress/Makefile @@ -5,7 +5,7 @@ # This calls the object directory makefile. That allows the objects to # be placed in the "current directory" which simplifies the Makefile. # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/test_regress/Makefile_obj b/test_regress/Makefile_obj index 5e1fa1424..81620d2f1 100644 --- a/test_regress/Makefile_obj +++ b/test_regress/Makefile_obj @@ -5,7 +5,7 @@ # # This is executed in the object directory, and called by ../Makefile # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/test_regress/driver.py b/test_regress/driver.py index 0e3849280..86ff9f340 100755 --- a/test_regress/driver.py +++ b/test_regress/driver.py @@ -1634,7 +1634,7 @@ class VlTest: return VtOs.run_capture(cmd, check=check) def setenv(self, var: str, val: str) -> None: - """Set enviornment variable""" + """Set environment variable""" print("\texport %s='%s'" % (var, val)) os.environ[var] = val @@ -2732,7 +2732,7 @@ if __name__ == '__main__': epilog="""driver.py invokes Verilator or another simulator on each test file. See docs/internals.rst in the distribution for more information. - Copyright 2024-2024 by Wilson Snyder. This program is free software; you + Copyright 2024-2025 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. diff --git a/test_regress/t/TestCheck.h b/test_regress/t/TestCheck.h index 0551634ac..d2a376f12 100644 --- a/test_regress/t/TestCheck.h +++ b/test_regress/t/TestCheck.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // -// Copyright 2013-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2013-2025 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. diff --git a/test_regress/t/TestSimulator.h b/test_regress/t/TestSimulator.h index a5fe6c53b..b99537a78 100644 --- a/test_regress/t/TestSimulator.h +++ b/test_regress/t/TestSimulator.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // -// Copyright 2013-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2013-2025 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. diff --git a/test_regress/t/TestVpi.h b/test_regress/t/TestVpi.h index a6dfac58d..4a87b8e51 100644 --- a/test_regress/t/TestVpi.h +++ b/test_regress/t/TestVpi.h @@ -1,7 +1,7 @@ // -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // -// Copyright 2013-2024 by Wilson Snyder. This program is free software; you can +// Copyright 2013-2025 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. diff --git a/verilator-config-version.cmake.in b/verilator-config-version.cmake.in index 92160d8fc..1624ae0ca 100644 --- a/verilator-config-version.cmake.in +++ b/verilator-config-version.cmake.in @@ -7,7 +7,7 @@ # # find_package(verilator 4.0) # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. diff --git a/verilator-config.cmake.in b/verilator-config.cmake.in index 3c00e1d86..33dcc4406 100644 --- a/verilator-config.cmake.in +++ b/verilator-config.cmake.in @@ -11,7 +11,7 @@ # add_executable(simulator ) # verilate(simulator SOURCES ) # -# Copyright 2003-2024 by Wilson Snyder. This program is free software; you +# Copyright 2003-2025 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. From f5e2f60dcc304ab6ccc98b54d18f23e13c8d30f3 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jan 2025 08:40:49 -0500 Subject: [PATCH 168/171] Update include/gtkwave from upstream --- include/gtkwave/fstapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/gtkwave/fstapi.c b/include/gtkwave/fstapi.c index 70f1bb171..ed818bfb8 100644 --- a/include/gtkwave/fstapi.c +++ b/include/gtkwave/fstapi.c @@ -3907,16 +3907,18 @@ while (value) static int fstVcdIDForFwrite(char *buf, unsigned int value) { char *pnt = buf; + int len = 0; /* zero is illegal for a value...it is assumed they start at one */ -while (value) +while (value && len <= 14) { value--; + ++len; *(pnt++) = (char)('!' + value % 94); value = value / 94; } -return(pnt - buf); +return len; } From 7d5772c749cdc5e02106336ecd9630071417b006 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jan 2025 08:45:29 -0500 Subject: [PATCH 169/171] Commentary: Changes update --- Changes | 1 + docs/spelling.txt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Changes b/Changes index e85dd88be..03537fd32 100644 --- a/Changes +++ b/Changes @@ -60,6 +60,7 @@ Verilator 5.031 devel * Fix interface bracketed array parameter access (#5677) (#5678). [Todd Strader] * Fix width extension of operands of `inside` operator (#5685). [Ryszard Rozak, Antmicro Ltd.] * Fix VPI + SYMRSVDWORD intersection (#5686). [Todd Strader] +* Fix verilator_gantt for hierarchically Verilated models (#5700). [Bartłomiej Chmiel, Antmicro Ltd.] Verilator 5.030 2024-10-27 diff --git a/docs/spelling.txt b/docs/spelling.txt index 6af921da4..9270968b7 100644 --- a/docs/spelling.txt +++ b/docs/spelling.txt @@ -294,6 +294,7 @@ NaN Nalbantis Nandor Narayan +Narcis Nassim Nauticus Newgard @@ -343,6 +344,7 @@ Redhat Reitan Renga Requin +Rodas Rodionov Rohan Rolfe From 4361c516fd6b86e2d2ec03bf086d27564cabfb55 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jan 2025 09:04:21 -0500 Subject: [PATCH 170/171] Commentary: Update contributors. --- docs/guide/contributors.rst | 234 +++++++++++++++++++----------------- 1 file changed, 122 insertions(+), 112 deletions(-) diff --git a/docs/guide/contributors.rst b/docs/guide/contributors.rst index eb8b24f92..504ca4698 100644 --- a/docs/guide/contributors.rst +++ b/docs/guide/contributors.rst @@ -34,130 +34,140 @@ MicroTune Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc., SiCortex Inc, Shunyao CAD, and Western Digital Inc. The contributors of major functionality are: Jeremy Bennett, Krzysztof -Bieganski, Byron Bradley, Lane Brooks, John Coiner, Duane Galbi, Geza Lore, -Todd Strader, Yutetsu Takatsukasa, Stefan Wallentowitz, Paul Wasson, Jie -Xu, and Wilson Snyder. +Bieganski, Byron Bradley, Lane Brooks, John Coiner, Duane Galbi, Arkadiusz +Kozdra, Geza Lore, Todd Strader, Yutetsu Takatsukasa, Stefan Wallentowitz, +Paul Wasson, Jie Xu, and Wilson Snyder. Some of the people who have provided ideas, and feedback for Verilator include: David Addison, Tariq B. Ahmad, Nikana Anastasiadis, John David Anglin, Frederic Antonin, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, Rohan -Arshid, Gökçe Aydos, Adam Bagley, Sharad Bagri, Robert Balas, Marco -Balboni, Matthew Ballance, Andrew Bardsley, Ilya Barkov, Matthew Barr, -Geoff Barrett, Kaleb Barrett, Daniel Bates, Julius Baxter, Michael Berman, -Jean Berniolles, Victor Besyakov, Narayan Bhagavatula, Moinak -Bhattacharyya, Kritik Bhimani, David Biancolin, David Binderman, Piotr -Binkowski, Johan Björk, David Black, Tymoteusz Blazejczyk, Scott Bleiweiss, -David van der Bokke, Daniel Bone, Guy Bonneau, Krzysztof Boroński, Gregg -Bouchard, Christopher Boumenot, Nick Bowler, Bryan Brady, Maarten De -Braekeleer, Charlie Brej, J Briquet, John Brownlee, KC Buckenmaier, Jeff -Bush, Lawrence Butcher, Tony Bybell, Iru Cai, Ted Campbell, Anthony Campos, -Chris Candler, Lauren Carlson, Gregory Carver, Donal Casey, Sebastien Van -Cauwenberghe, Alex Chadwick, Greg Chadwick, Marcel Chang, Aliaksei -Chapyzhenka, Chih-Mao Chen, Guokai Chen, Terry Chen, Yi-Chung Chen, Yurii -Cherkasov, Hennadii Chernyshchyk, Enzo Chi, Robert A. Clark, Ryan Clarke, -Allan Cochrane, Keith Colbert, Quentin Corradi, Nassim Corteggiani, +Arshid, Valentin Atepalikhin, Philip Axer, Gökçe Aydos, Chris Bachhuber, +Filip Badáň, Adam Bagley, Sharad Bagri, James Bailey, Robert Balas, Marco +Balboni, Matthew Ballance, Ricardo Barbedo, Andrew Bardsley, Ilya Barkov, +Matthew Barr, Geoff Barrett, Kaleb Barrett, Daniel Bates, Julius Baxter, +Michael Berman, Jean Berniolles, Victor Besyakov, Narayan Bhagavatula, +Moinak Bhattacharyya, Kritik Bhimani, David Biancolin, Krzysztof Bieganski, +Michael Bikovitsky, David Binderman, Piotr Binkowski, Johan Björk, David +Black, Tymoteusz Blazejczyk, Scott Bleiweiss, David van der Bokke, Daniel +Bone, Guy Bonneau, Krzysztof Boroński, Gregg Bouchard, Christopher +Boumenot, Paul Bowen-Huggett, Nick Bowler, Bryan Brady, Maarten De +Braekeleer, Liam Braun, Charlie Brej, J Briquet, John Brownlee, KC +Buckenmaier, Gijs Burghoorn, Jeff Bush, Lawrence Butcher, Tony Bybell, Iru +Cai, Ted Campbell, Anthony Campos, Chris Candler, Lauren Carlson, Gregory +Carver, Donal Casey, Sebastien Van Cauwenberghe, Alex Chadwick, Greg +Chadwick, Marcel Chang, Aliaksei Chapyzhenka, Chih-Mao Chen, Guokai Chen, +Kefa Chen, Terry Chen, Yangyu Chen, Yi-Chung Chen, Yurii Cherkasov, +Hennadii Chernyshchyk, Enzo Chi, Bartłomiej Chmiel, Robert A. Clark, Ryan +Clarke, Allan Cochrane, Keith Colbert, Quentin Corradi, Nassim Corteggiani, Gianfranco Costamagna, February Cozzocrea, Sean Cross, George Cuan, Michal Czyz, Joe DErrico, Jim Dai, Lukasz Dalek, Laurens van Dam, Gunter -Dannoritzer, Ashutosh Das, Julian Daube, Bernard Deadman, Peter Debacker, -John Demme, Mike Denio, John Deroo, Philip Derrick, Aadi Desai, John -Dickol, Ruben Diez, Danny Ding, Jacko Dirks, Ivan Djordjevic, Brad Dobbie, -Paul Donahue, Jonathon Donaldson, Anthony Donlon, Caleb Donovick, Larry -Doolittle, Leendert van Doorn, Sebastian Dressler, Jonathan Drolet, Maciej -Dudek, Alex Duller, Jeff Dutton, Tomas Dzetkulic, Usuario Eda, Charles -Eddleston, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Trevor Elbourne, -Mats Engstrom, Robert Farrell, Julien Faucher, Olivier Faure, Eugen Fekete, -Fabrizio Ferrandi, Udi Finkelstein, Brian Flachs, Bill Flynn, Andrea -Foletto, Alex Forencich, Aurelien Francillon, Bob Fredieu, Manuel -Freiberger, Mostafa Gamal, Vito Gamberini, Mostafa Garnal, Benjamin -Gartner, Christian Gelinek, Richard E George, Peter Gerst, Glen Gibb, -Michael Gielda, Barbara Gigerl, Nimrod Gileadi, Shankar Giri, Dan -Gisselquist, Petr Gladkikh, Sam Gladstone, Mariusz Glebocki, Embedded Go, -Andrew Goessling, Amir Gonnen, Chitlesh Goorah, Tomasz Gorochowik, Kai -Gossner, Tarik Graba, Sergi Granell, Al Grant, Nathan Graybeal, Alexander -Grobman, Qian Gu, Xuan Guo, Prabhat Gupta, Driss Hafdi, Neil Hamilton, -James Hanlon, Tang Haojin, Øyvind Harboe, Jannis Harder, David Harris, -Junji Hashimoto, Thomas Hawkins, Mitch Hayenga, Harald Heckmann, Robert -Henry, Stephen Henry, Sebastian Hesselbarth, David Hewson, Jamey Hicks, -Joel Holdsworth, Andrew Holme, Peter Holmes, Hiroki Honda, Alex Hornung, +Dannoritzer, Ashutosh Das, Julian Daube, Greg Davill, Bernard Deadman, +Peter Debacker, Josse Van Delm, John Demme, Mike Denio, John Deroo, Philip +Derrick, Aadi Desai, John Dickol, Ruben Diez, Danny Ding, Jacko Dirks, Ivan +Djordjevic, Brad Dobbie, Paul Donahue, Jonathon Donaldson, Anthony Donlon, +Caleb Donovick, Larry Doolittle, Leendert van Doorn, Sebastian Dressler, +Jonathan Drolet, Justin Yao Du, Maciej Dudek, Alex Duller, Jeff Dutton, +Tomas Dzetkulic, Usuario Eda, Charles Eddleston, Chandan Egbert, Joe Eiler, +Ahmed El-Mahmoudy, Trevor Elbourne, Mats Engstrom, Robert Farrell, Julien +Faucher, Olivier Faure, Eugene Feinberg, Eugen Fekete, Fabrizio Ferrandi, +Udi Finkelstein, Brian Flachs, Bill Flynn, Andrea Foletto, Alex Forencich, +Aurelien Francillon, Bob Fredieu, Manuel Freiberger, Mostafa Gamal, Vito +Gamberini, Mostafa Garnal, Benjamin Gartner, Christian Gelinek, Richard E +George, Peter Gerst, Glen Gibb, Michael Gielda, Barbara Gigerl, Nimrod +Gileadi, Shankar Giri, Dan Gisselquist, Szymon Gizler, Petr Gladkikh, Sam +Gladstone, Mariusz Glebocki, Embedded Go, Andrew Goessling, Amir Gonnen, +Chitlesh Goorah, Tomasz Gorochowik, Kai Gossner, Tarik Graba, Sergi +Granell, Al Grant, Nathan Graybeal, Alexander Grobman, Qian Gu, Xuan Guo, +Prabhat Gupta, Deniz Güzel, Driss Hafdi, Abdul Hameed, Neil Hamilton, James +Hanlon, Tang Haojin, Øyvind Harboe, Jannis Harder, David Harris, Junji +Hashimoto, Thomas Hawkins, Mitch Hayenga, Harald Heckmann, Robert Henry, +Stephen Henry, Sebastian Hesselbarth, David Hewson, Jamey Hicks, Joel +Holdsworth, Andrew Holme, Peter Holmes, Hiroki Honda, Alex Hornung, Pierre-Henri Horrein, David Horton, Peter Horvath, Jae Hossell, Kuoping -Hsu, Teng Huang, Steven Hugg, Huanghuang Zhou, Alan Hunter, James -Hutchinson, Tim Hutt, Ehab Ibrahim, Edgar E. Iglesias, Shahid Ikram, Jamie -Iles, Vighnesh Iyer, Ben Jackson, Daniel Jacques, Shareef Jalloq, Marlon +Hsu, Shou-Li Hsu, Teng Huang, Steven Hugg, Alan Hunter, James Hutchinson, +Tim Hutt, Ehab Ibrahim, Edgar E. Iglesias, Shahid Ikram, Jamie Iles, Fuad +Ismail, Vighnesh Iyer, Ben Jackson, Daniel Jacques, Shareef Jalloq, Marlon James, Krzysztof Jankowski, Eyck Jentzsch, HyungKi Jeong, Iztok Jeras, -Alexandre Joannou, James Johnson, Christophe Joly, Justin Jones, -William D. Jones, Larry Darryl Lee Jr., Franck Jullien, James Jung, -Yoshitomo Kaneda, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand -Kamendje, Vasu Kandadi, Kanad Kanhere, Patricio Kaplan, Pieter Kapsenberg, -Rafal Kapuscik, Ralf Karge, Per Karlsson, Dan Katz, Sol Katzman, Ian -Kennedy, Ami Keren, Michael Killough, Sun Kim, Jonathan Kimmitt, Olof -Kindgren, Kevin Kiningham, Cameron Kirk, Dan Kirkham, Aleksander Kiryk, -Sobhan Klnv, Gernot Koch, Jack Koenig, Soon Koh, Nathan Kohagen, Steve -Kolecki, Brett Koonce, Will Korteland, Andrei Kostovski, Wojciech Koszek, -Varun Koyyalagunta, Arkadiusz Kozdra, Markus Krause, David Kravitz, Adam -Krolnik, Roland Kruse, Mahesh Kumashikar, Andreas Kuster, Sergey Kvachonok, -Charles Eric LaForest, Kevin Laeufer, Ed Lander, Steve Lang, Pierre -Laroche, Stephane Laurent, Walter Lavino, Christian Leber, David Ledger, -Alex Lee, Larry Lee, Yoda Lee, Michaël Lefebvre, Dag Lem, Igor Lesik, John -Li, Kay Li, Zixi Li, Davide Libenzi, Nandor Licker, Eivind Liland, Ícaro -Lima, Kevin Lin, Yu-Sheng Lin, Charlie Lind, Andrew Ling, Jiuyang Liu, Joey -Liu, Paul Liu, Derek Lockhart, Jake Longo, Arthur Low, Jose Loyola, Stefan -Ludwig, Dan Lussier, Konstantin Lübeck, Fred Ma, Liwei Ma, Duraid Madina, -Oleh Maksymenko, Affe Mao, Julien Margetts, Chick Markley, Alexis Marquet, -Mark Marshall, Alfonso Martinez, Unai Martinez-Corral, Adrien Le Masle, -Yves Mathieu, Vladimir Matveyenko, Patrick Maupin, Stan Mayer, Conor -McCullough, Jason McMullan, Elliot Mednick, Yuan Mei, Andy Meier, +Pawel Jewstafjew, Alexandre Joannou, James Johnson, Christophe Joly, Justin +Jones, William D. Jones, Abe Jordan, Larry Darryl Lee Jr., Franck Jullien, +James Jung, Mike Kagen, Arthur Kahlich, Kaalia Kahn, Guy-Armand Kamendje, +Vasu Kandadi, Yoshitomo Kaneda, Kanad Kanhere, Patricio Kaplan, Pieter +Kapsenberg, Rafal Kapuscik, Ralf Karge, Per Karlsson, Dan Katz, Sol +Katzman, Ian Kennedy, Ami Keren, Fabian Keßler, Michael Killough, Sun Kim, +Jonathan Kimmitt, Olof Kindgren, Kevin Kiningham, Cameron Kirk, Dan +Kirkham, Aleksander Kiryk, Sobhan Klnv, Gernot Koch, Jack Koenig, Soon Koh, +Nathan Kohagen, Steve Kolecki, Brett Koonce, Will Korteland, Andrei +Kostovski, Wojciech Koszek, Varun Koyyalagunta, Arkadiusz Kozdra, Markus +Krause, David Kravitz, Adam Krolnik, Roland Kruse, Mahesh Kumashikar, +Andreas Kuster, Sergey Kvachonok, Charles Eric LaForest, Kevin Laeufer, Ed +Lander, Steve Lang, Pierre Laroche, Stephane Laurent, Walter Lavino, +Christian Leber, David Ledger, Alex Lee, Larry Lee, Yoda Lee, Michaël +Lefebvre, Dag Lem, Igor Lesik, John Li, Kay Li, Zixi Li, Davide Libenzi, +Nandor Licker, Eivind Liland, Ícaro Lima, Kevin Lin, Yu-Sheng Lin, Charlie +Lind, Andrew Ling, Jiuyang Liu, Joey Liu, Paul Liu, Derek Lockhart, Jake +Longo, Geza Lore, Arthur Low, Jose Loyola, Stefan Ludwig, Dan Lussier, +Konstantin Lübeck, Fred Ma, Liwei Ma, Duraid Madina, Oleh Maksymenko, Affe +Mao, Julien Margetts, Chick Markley, Alexis Marquet, Mark Marshall, Alfonso +Martinez, Unai Martinez-Corral, Adrien Le Masle, Yves Mathieu, Vladimir +Matveyenko, Patrick Maupin, Stan Mayer, Jordan McConnon, Conor McCullough, +Jason McMullan, Elliot Mednick, Yuan Mei, Andy Meier, Luiza de Melo, Rodrigo A. Melo, Benjamin Menküc, Jake Merdich, David Metz, Wim Michiels, -Miodrag Milanović, Darryl Miles, Kevin Millis, Andrew Miloradovsky, Wai Sum -Mong, Peter Monsson, Sean Moore, Stuart Morris, Dennis Muhlestein, John -Murphy, Matt Myers, Nathan Myers, Richard Myers, Alex Mykyta, Dimitris -Nalbantis, Peter Nelson, Felix Neumärker, Bob Newgard, Cong Van Nguyen, -Rachit Nigam, Toru Niina, Paul Nitza, Yossi Nivin, Pete Nixon, Lisa Noack, -Mark Nodine, Michael Nolan, Andrew Nolte, Joseph Nwabueze, Kuba Ober, -Andreas Olofsson, Baltazar Ortiz, Aleksander Osman, Don Owen, Tim Paine, -Deepa Palaniappan, James Pallister, Vassilis Papaefstathiou, Sanggyu Park, -Brad Parker, Risto Pejašinović, Morten Borup Petersen, Dan Petrisko, Wesley -Piard, Maciej Piechotka, David Pierce, Cody Piersall, T. Platz, Michael -Platzer, Dominic Plunkett, David Poole, Michael Popoloski, Roman Popov, -Aylon Chaim Porat, Oron Port, Rich Porter, Rick Porter, Stefan Post, -Niranjan Prabhu, Damien Pretet, Harald Pretl, Bill Pringlemeir, Usha -Priyadharshini, Mark Jackson Pulver, Prateek Puri, Jiacheng Qian, Marshal -Qiao, Raynard Qiao, Yujia Qiao, Jasen Qin, Frank Qiu, Nandu Raj, Kamil -Rakoczy, Danilo Ramos, Drew Ranck, Chris Randall, Anton Rapp, Josh Redford, -Odd Magne Reitan, Frédéric Requin, Dustin Richmond, Samuel Riedel, Alberto -Del Rio, Eric Rippey, Oleg Rodionov, Ludwig Rogiers, Paul Rolfe, Michail -Rontionov, Arjen Roodselaar, Tobias Rosenkranz, Yernagula Roshit, Ryszard +Miodrag Milanović, Darryl Miles, Kevin Millis, Andrew Miloradovsky, David +Moberg, Wai Sum Mong, Peter Monsson, Anthony Moore, Sean Moore, Stuart +Morris, Dennis Muhlestein, John Murphy, Matt Myers, Nathan Myers, Richard +Myers, Alex Mykyta, Eric Müller, Dimitris Nalbantis, Peter Nelson, Felix +Neumärker, Bob Newgard, Cong Van Nguyen, Rachit Nigam, Toru Niina, Paul +Nitza, Yossi Nivin, Pete Nixon, Lisa Noack, Mark Nodine, Michael Nolan, +Andrew Nolte, Joseph Nwabueze, Kevin Nygaard, Kuba Ober, Krzysztof +Obłonczek, Andreas Olofsson, Baltazar Ortiz, Aleksander Osman, Don Owen, +Tim Paine, Deepa Palaniappan, James Pallister, Vassilis Papaefstathiou, +Sanggyu Park, Brad Parker, Risto Pejašinović, Seth Pellegrino, Morten Borup +Petersen, Dan Petrisko, Wesley Piard, Maciej Piechotka, David Pierce, Cody +Piersall, T. Platz, Michael Platzer, Dominic Plunkett, Nolan Poe, David +Poole, Michael Popoloski, Roman Popov, Aylon Chaim Porat, Oron Port, Rich +Porter, Rick Porter, Stefan Post, Niranjan Prabhu, Damien Pretet, Harald +Pretl, Bill Pringlemeir, Usha Priyadharshini, Mark Jackson Pulver, Prateek +Puri, Han Qi, Jiacheng Qian, Marshal Qiao, Raynard Qiao, Yujia Qiao, Jasen +Qin, Frank Qiu, Nandu Raj, Kamil Rakoczy, Danilo Ramos, Drew Ranck, Chris +Randall, Anton Rapp, Josh Redford, Odd Magne Reitan, Frédéric Requin, +Dustin Richmond, Samuel Riedel, Alberto Del Rio, Eric Rippey, Narcis Rodas, +Oleg Rodionov, Ludwig Rogiers, Paul Rolfe, Michail Rontionov, Arjen +Roodselaar, Arthur Rosa, Tobias Rosenkranz, Yernagula Roshit, Ryszard Rozak, Huang Rui, Graham Rushton, Jan Egil Ruud, Denis Rystsov, Pawel -Sagan, Robert Sammelson, John Sanguinetti, Josep Sans, Luca Sasselli, -Martin Scharrer, Martin Schmidt, Julie Schwartz, Galen Seitz, Joseph -Shaker, Mark Shaw, Salman Sheikh, Zhou Shen, Hao Shi, James Shi, Michael -Shinkarovsky, Rafael Shirakawa, Jeffrey Short, S Shuba, Fan Shupei, Ethan -Sifferman, Anderson Ignacio da Silva, Rodney Sinclair, Ameya Vikram Singh, -Sanjay Singh, Frans Skarman, Nate Slager, Steven Slatter, Mladen -Slijepcevic, Brian Small, Garrett Smith, Gus Smith, Tim Snyder, Maciej -Sobkowski, Stan Sokorac, Alex Solomatnikov, Flavien Solt, Wei Song, Trefor -Southwell, Martin Stadler, Art Stamness, David Stanford, John Stevenson, -Pete Stevenson, Patrick Stewart, Rob Stoddard, Tood Strader, John Stroebel, -Ray Strouble, Sven Stucki, Howard Su, Emerson Suguimoto, Gene Sullivan, -Qingyao Sun, Renga Sundararajan, Kuba Sunderland-Ober, Gustav Svensk, -Rupert Swarbrick, Jevin Sweval, Shinya T-Y, Thierry Tambe, Jesse Taube, -Drew Taussig, Jose Tejada, Sören Tempel, Peter Tengstrand, Wesley Terpstra, -Rui Terra, Stefan Thiede, Justin Thiel, Gary Thomas, Ian Thompson, Kevin -Thompson, Mike Thyer, Hans Tichelaar, Tudor Timi, Viktor Tomov, Steve Tong, -Topa Topino, Àlex Torregrosa, Topa Tota, Michael Tresidder, Lenny Truong, -David Turner, Neil Turton, Hideto Ueno, Mike Urbach, Joel Vandergriendt, -Srini Vemuri, Srinivasan Venkataramanan, Yuri Victorovich, Ivan Vnučec, -Bogdan Vukobratovic, Holger Waechtler, Philipp Wagner, Johannes Walter, CY -Wang, Chuxuan Wang, Shawn Wang, Zhanglei Wang, Greg Waters, Thomas Watts, -Eugene Weber, John Wehle, Tianrui Wei, David Welch, Thomas J Whatson, -Martin Whitaker, Marco Widmer, Leon Wildman, Daniel S. Wilkerson, Daniel -Wilkerson, Gerald Williams, Trevor Williams, Don Williamson, Jan Van -Winkel, Jeff Winston, Joshua Wise, Clifford Wolf, Johan Wouters, Paul -Wright, Tobias Wölfel, Junyi Xi, Ding Xiaoliang, Liu Xiaoyi, Mandy Xu, -Shanshan Xu, Yinan Xu, SU YANG, Felix Yan, Luke Yang, Amir Yazdanbakhsh, -Chentai (Seven) Yuan, Florian Zaruba, Mat Zeno, Keyi Zhang, Xi Zhang, Yike -Zhou, Jiamin Zhu. +Sagan, Robert Sammelson, Adrian Sampson, John Sanguinetti, Josep Sans, Luca +Sasselli, Martin Scharrer, Martin Schmidt, Jonathan Schröter, Julie +Schwartz, Galen Seitz, Sam Shahrestani, Joseph Shaker, Mark Shaw, Salman +Sheikh, Zhou Shen, Hao Shi, James Shi, Michael Shinkarovsky, Rafael +Shirakawa, Jeffrey Short, S Shuba, Fan Shupei, Ethan Sifferman, Anderson +Ignacio da Silva, Rodney Sinclair, Ameya Vikram Singh, Sanjay Singh, Frans +Skarman, Nate Slager, Steven Slatter, Mladen Slijepcevic, Brian Small, +Garrett Smith, Gus Smith, Tim Snyder, Maciej Sobkowski, Stan Sokorac, Alex +Solomatnikov, Flavien Solt, Wei Song, Trefor Southwell, Martin Stadler, Art +Stamness, David Stanford, Krzysztof Starecki, Baruch Sterin, John +Stevenson, Pete Stevenson, Patrick Stewart, Rob Stoddard, Tood Strader, +John Stroebel, Ray Strouble, Sven Stucki, Howard Su, Udaya Raj Subedi, +Emerson Suguimoto, Gene Sullivan, Qingyao Sun, Renga Sundararajan, Kuba +Sunderland-Ober, Gustav Svensk, Rupert Swarbrick, Jevin Sweval, Paul +Swirhun, Shinya T-Y, Thierry Tambe, Jesse Taube, Drew Taussig, Christopher +Taylor, Greg Taylor, Jose Tejada, Sören Tempel, Peter Tengstrand, Wesley +Terpstra, Rui Terra, Stefan Thiede, Justin Thiel, Gary Thomas, Ian +Thompson, Kevin Thompson, Mike Thyer, Hans Tichelaar, Tudor Timi, Viktor +Tomov, Steve Tong, Topa Topino, Àlex Torregrosa, Topa Tota, Michael +Tresidder, Lenny Truong, David Turner, Neil Turton, Hideto Ueno, Mike +Urbach, Joel Vandergriendt, Srini Vemuri, Srinivasan Venkataramanan, Yuri +Victorovich, Ivan Vnučec, Bogdan Vukobratovic, Holger Waechtler, Philipp +Wagner, Stefan Wallentowitz, Johannes Walter, CY Wang, Chuxuan Wang, Shawn +Wang, Yilou Wang, Zhanglei Wang, Greg Waters, Thomas Watts, Eugene Weber, +John Wehle, Tianrui Wei, David Welch, Thomas J Whatson, Martin Whitaker, +Marco Widmer, Leon Wildman, Daniel S. Wilkerson, Daniel Wilkerson, Gerald +Williams, Trevor Williams, Don Williamson, Jan Van Winkel, Jeff Winston, +Joshua Wise, Clifford Wolf, Johan Wouters, Paul Wright, Tobias Wölfel, +Junyi Xi, Ding Xiaoliang, Liu Xiaoyi, Jinyan Xu, Mandy Xu, Pengcheng Xu, +Shanshan Xu, Yan Xu, Yinan Xu, SU YANG, Felix Yan, Jiaxun Yang, Luke Yang, +Amir Yazdanbakhsh, Chentai (Seven) Yuan, Florian Zaruba, Mat Zeno, Keyi +Zhang, Xi Zhang, Huanghuang Zhou, Yike Zhou, Jiamin Zhu, Ryan Ziegler. Thanks to them, and all those we've missed mentioning above, and to those whom have wished to remain anonymous. From 8ff77e9d47351b0a59114929880687839a51840b Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 1 Jan 2025 09:04:41 -0500 Subject: [PATCH 171/171] Version bump --- CMakeLists.txt | 2 +- Changes | 2 +- configure.ac | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0edca19e0..911751a8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.15) cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime project( Verilator - VERSION 5.031 + VERSION 5.032 HOMEPAGE_URL https://verilator.org LANGUAGES CXX ) diff --git a/Changes b/Changes index 03537fd32..d2121e117 100644 --- a/Changes +++ b/Changes @@ -8,7 +8,7 @@ The changes in each Verilator version are described below. The contributors that suggested a given feature are shown in []. Thanks! -Verilator 5.031 devel +Verilator 5.032 2025-01-01 ========================== **Minor:** diff --git a/configure.ac b/configure.ac index cb740447c..a7e1b8976 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ # Then 'make maintainer-dist' #AC_INIT([Verilator],[#.### YYYY-MM-DD]) #AC_INIT([Verilator],[#.### devel]) -AC_INIT([Verilator],[5.031 devel], +AC_INIT([Verilator],[5.032 2025-01-01], [https://verilator.org], [verilator],[https://verilator.org])