From 1857f6399c0ef38bc85f75df0dc1b6476419e941 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 21 Feb 2025 17:18:49 -0500 Subject: [PATCH] Fix `$monitor` with dotted references (#5794). --- Changes | 1 + src/V3Assert.cpp | 5 +- src/V3AstNodes.cpp | 2 +- test_regress/t/t_sys_monitor_dotted.py | 18 +++++ test_regress/t/t_sys_monitor_dotted.v | 94 ++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_sys_monitor_dotted.py create mode 100644 test_regress/t/t_sys_monitor_dotted.v diff --git a/Changes b/Changes index a13ab3d18..3ff0a8d24 100644 --- a/Changes +++ b/Changes @@ -57,6 +57,7 @@ Verilator 5.033 devel * Fix ignoring joins in stringify in preprocessor (#5777). [Krzysztof Bieganski, Antmicro Ltd.] * Fix unpacked split_var (#5782) (#5785). [Yutetsu TAKATSUKASA] * Fix time import error on time parameters (#5786). [Luca Colagrande] +* Fix `$monitor` with dotted references (#5794). [Ahmed Elzeftawi] * Fix matching language extension options including dots. diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp index 85d65a561..9ca686a7b 100644 --- a/src/V3Assert.cpp +++ b/src/V3Assert.cpp @@ -534,8 +534,9 @@ class AssertVisitor final : public VNVisitor { while (monExprsp) { if (AstNodeVarRef* varrefp = VN_CAST(monExprsp, NodeVarRef)) { AstSenItem* const senItemp - = new AstSenItem(fl, VEdgeType::ET_CHANGED, - new AstVarRef{fl, varrefp->varp(), VAccess::READ}); + = new AstSenItem{fl, VEdgeType::ET_CHANGED, + // Clone so get VarRef or VarXRef as needed + varrefp->cloneTree(false)}; if (!monSenItemsp) { monSenItemsp = senItemp; } else { diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index f0ee72c84..9e20b8b07 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1787,7 +1787,7 @@ void AstClocking::dumpJson(std::ostream& str) const { } void AstDisplay::dump(std::ostream& str) const { this->AstNodeStmt::dump(str); - // str << " " << displayType().ascii(); + str << " [" << displayType().ascii() << "]"; } void AstDisplay::dumpJson(std::ostream& str) const { dumpJsonGen(str); } void AstEnumDType::dump(std::ostream& str) const { diff --git a/test_regress/t/t_sys_monitor_dotted.py b/test_regress/t/t_sys_monitor_dotted.py new file mode 100755 index 000000000..bd059b0f2 --- /dev/null +++ b/test_regress/t/t_sys_monitor_dotted.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/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_sys_monitor_dotted.v b/test_regress/t/t_sys_monitor_dotted.v new file mode 100644 index 000000000..92ac9b4b0 --- /dev/null +++ b/test_regress/t/t_sys_monitor_dotted.v @@ -0,0 +1,94 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +interface addsub_ifc; + logic [7:0] a, b; + logic doAdd0; + logic clk; + logic rst_n; + logic [7:0] result; + logic overflow; +endinterface + +module adder_sub_8bit + ( + input logic clk, + input logic rst_n, + input logic [7:0] a, + input logic [7:0] b, + input logic doAdd0, + output logic [7:0] result, + output logic overflow + ); + + logic [7:0] b_modified; + logic [8:0] temp_result; + + assign b_modified = doAdd0 ? b : ~b + 8'b1; + + always_comb begin + temp_result = {1'b0, a} + {1'b0, b_modified}; + end + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + result <= 8'h0; + overflow <= 1'b0; + end else begin + result <= temp_result[7:0]; + overflow <= (a[7] == b_modified[7] && result[7] != a[7]); + end + end + +endmodule + +module t; + addsub_ifc dut_ifc(); + + adder_sub_8bit dut + ( + .clk(dut_ifc.clk), + .rst_n(dut_ifc.rst_n), + .a(dut_ifc.a), + .b(dut_ifc.b), + .doAdd0(dut_ifc.doAdd0), + .result(dut_ifc.result), + .overflow(dut_ifc.overflow) + ); + + initial begin + dut_ifc.clk = 0; + forever #5 dut_ifc.clk = ~dut_ifc.clk; + end + + initial begin + dut_ifc.rst_n = 0; + dut_ifc.a = 8'h0; + dut_ifc.b = 8'h0; + dut_ifc.doAdd0 = 1'b1; + + #10 dut_ifc.rst_n = 1; + + #10; + dut_ifc.a = 8'h35; + dut_ifc.b = 8'h42; + dut_ifc.doAdd0 = 1'b1; + + #20; + $write("*-* All Finished *-*\n"); + $finish; + end + + initial begin + $display("[%0t] Initial rst_n=%b a=%h b=%h doAdd0=%b result=%h overflow=%b", + $time, dut_ifc.rst_n, dut_ifc.a, dut_ifc.b, + dut_ifc.doAdd0, dut_ifc.result, dut_ifc.overflow); + $monitor("[%0t] Monitor rst_n=%b a=%h b=%h doAdd0=%b result=%h overflow=%b", + $time, dut_ifc.rst_n, dut_ifc.a, dut_ifc.b, + dut_ifc.doAdd0, dut_ifc.result, dut_ifc.overflow); + end + +endmodule