From 22656d6fdd2c2e8065fb167a51c732f04bee1544 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 5 Mar 2022 20:17:36 -0500 Subject: [PATCH] Fix Vdeeptemp error with --threads and --compiler clang (#3338). --- Changes | 1 + src/V3AstNodes.h | 7 +++ src/V3Depth.cpp | 24 +++++++++- test_regress/t/t_depth_flop.pl | 18 ++++++++ test_regress/t/t_depth_flop.v | 83 ++++++++++++++++++++++++++++++++++ 5 files changed, 131 insertions(+), 2 deletions(-) create mode 100755 test_regress/t/t_depth_flop.pl create mode 100644 test_regress/t/t_depth_flop.v diff --git a/Changes b/Changes index 551867530..38edaa32e 100644 --- a/Changes +++ b/Changes @@ -24,6 +24,7 @@ Verilator 4.219 devel * Fix unnamedblk error on foreach (#3321). [Aliaksei Chapyzhenka] * Fix crash in recursive module inlining (#3324). [Larry Doolittle] * Fix compile error with --trace-fst --sc (#3332). [leavinel] +* Fix Vdeeptemp error with --threads and --compiler clang (#3338). [Per Karlsson] Verilator 4.218 2022-01-17 diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 4e0b793c7..984fcb112 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -9185,6 +9185,13 @@ public: } AstNode* stmtsp() const { return op1p(); } void addStmtsp(AstNode* nodep) { addOp1p(nodep); } + void addStmtsFirstp(AstNode* nodep) { + if (stmtsp()) { + stmtsp()->addHereThisAsNext(nodep); + } else { + addStmtsp(nodep); + } + } ExecMTask* execMTaskp() const { return m_execMTaskp; } void execMTaskp(ExecMTask* execMTaskp) { m_execMTaskp = execMTaskp; } virtual void dump(std::ostream& str = std::cout) const override; diff --git a/src/V3Depth.cpp b/src/V3Depth.cpp index 6f3c65b8d..d83d69d66 100644 --- a/src/V3Depth.cpp +++ b/src/V3Depth.cpp @@ -41,6 +41,7 @@ private: // STATE AstCFunc* m_cfuncp = nullptr; // Current block + AstMTaskBody* m_mtaskbodyp = nullptr; // Current mtaskbody AstNode* m_stmtp = nullptr; // Current statement int m_depth = 0; // How deep in an expression int m_maxdepth = 0; // Maximum depth in an expression @@ -54,8 +55,13 @@ private: // if (debug() >= 9) nodep->dumpTree(cout, "deep:"); AstVar* const varp = new AstVar{nodep->fileline(), VVarType::STMTTEMP, m_tempNames.get(nodep), nodep->dtypep()}; - UASSERT_OBJ(m_cfuncp, nodep, "Deep expression not under a function"); - m_cfuncp->addInitsp(varp); + if (m_cfuncp) { + m_cfuncp->addInitsp(varp); + } else if (m_mtaskbodyp) { + m_mtaskbodyp->addStmtsFirstp(varp); + } else { + nodep->v3fatalSrc("Deep expression not under a function"); + } // Replace node tree with reference to var AstVarRef* const newp = new AstVarRef{nodep->fileline(), varp, VAccess::READ}; nodep->replaceWith(newp); @@ -71,14 +77,28 @@ private: // VISITORS virtual 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); } } + virtual 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); + } + } void visitStmt(AstNodeStmt* nodep) { VL_RESTORER(m_stmtp); { diff --git a/test_regress/t/t_depth_flop.pl b/test_regress/t/t_depth_flop.pl new file mode 100755 index 000000000..dabf3116e --- /dev/null +++ b/test_regress/t/t_depth_flop.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(vltmt => 1); # Note issue shows up with --threads + +compile( + verilator_flags2 => ['--compiler clang --threads 2 -Wno-UNOPTTHREADS'], + ); + +ok(1); +1; diff --git a/test_regress/t/t_depth_flop.v b/test_regress/t/t_depth_flop.v new file mode 100644 index 000000000..f6aa674c0 --- /dev/null +++ b/test_regress/t/t_depth_flop.v @@ -0,0 +1,83 @@ +// 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 + +module t(/*AUTOARG*/ + // Outputs + out, + // Inputs + clk_0, clk_1, clk_2, clk_3, clk_4, clk_5, clk_6, clk_7, clk_8, clk_9, clk_10, + clk_11, clk_12, clk_13, clk_14, clk_15, clk_16, clk_17, clk_18, clk_19, + rstn_0, rstn_1, rstn_2, rstn_3, rstn_4, rstn_5, rstn_6, rstn_7, rstn_8, + rstn_9, rstn_10, rstn_11, rstn_12, rstn_13, rstn_14, rstn_15, rstn_16, + rstn_17, rstn_18, rstn_19 + ); + + input clk_0; + input clk_1; + input clk_2; + input clk_3; + input clk_4; + input clk_5; + input clk_6; + input clk_7; + input clk_8; + input clk_9; + input clk_10; + input clk_11; + input clk_12; + input clk_13; + input clk_14; + input clk_15; + input clk_16; + input clk_17; + input clk_18; + input clk_19; + input rstn_0; + input rstn_1; + input rstn_2; + input rstn_3; + input rstn_4; + input rstn_5; + input rstn_6; + input rstn_7; + input rstn_8; + input rstn_9; + input rstn_10; + input rstn_11; + input rstn_12; + input rstn_13; + input rstn_14; + input rstn_15; + input rstn_16; + input rstn_17; + input rstn_18; + input rstn_19; + + // verilator lint_off MULTIDRIVEN + output reg out [0:29-1]; + + always_ff @(posedge clk_0, negedge rstn_0) if ((rstn_0 == 0)) out[0] <= 0; + always_ff @(posedge clk_1, negedge rstn_1) if ((rstn_1 == 0)) out[1] <= 0; + always_ff @(posedge clk_2, negedge rstn_2) if ((rstn_2 == 0)) out[2] <= 0; + always_ff @(posedge clk_3, negedge rstn_3) if ((rstn_3 == 0)) out[3] <= 0; + always_ff @(posedge clk_4, negedge rstn_4) if ((rstn_4 == 0)) out[4] <= 0; + always_ff @(posedge clk_5, negedge rstn_5) if ((rstn_5 == 0)) out[5] <= 0; + always_ff @(posedge clk_6, negedge rstn_6) if ((rstn_6 == 0)) out[6] <= 0; + always_ff @(posedge clk_7, negedge rstn_7) if ((rstn_7 == 0)) out[7] <= 0; + always_ff @(posedge clk_8, negedge rstn_8) if ((rstn_8 == 0)) out[8] <= 0; + always_ff @(posedge clk_9, negedge rstn_9) if ((rstn_9 == 0)) out[9] <= 0; + always_ff @(posedge clk_10, negedge rstn_10) if ((rstn_10 == 0)) out[10] <= 0; + always_ff @(posedge clk_11, negedge rstn_11) if ((rstn_11 == 0)) out[11] <= 0; + always_ff @(posedge clk_12, negedge rstn_12) if ((rstn_12 == 0)) out[12] <= 0; + always_ff @(posedge clk_13, negedge rstn_13) if ((rstn_13 == 0)) out[13] <= 0; + always_ff @(posedge clk_14, negedge rstn_14) if ((rstn_14 == 0)) out[14] <= 0; + always_ff @(posedge clk_15, negedge rstn_15) if ((rstn_15 == 0)) out[15] <= 0; + always_ff @(posedge clk_16, negedge rstn_16) if ((rstn_16 == 0)) out[16] <= 0; + always_ff @(posedge clk_17, negedge rstn_17) if ((rstn_17 == 0)) out[17] <= 0; + always_ff @(posedge clk_18, negedge rstn_18) if ((rstn_18 == 0)) out[18] <= 0; + always_ff @(posedge clk_19, negedge rstn_19) if ((rstn_19 == 0)) out[19] <= 0; + +endmodule