mirror of
https://github.com/verilator/verilator.git
synced 2024-12-29 10:47:34 +00:00
Fix module automatic
This commit is contained in:
parent
e223228ec0
commit
192236a832
@ -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); }
|
||||
|
18
test_regress/t/t_mod_automatic.py
Executable file
18
test_regress/t/t_mod_automatic.py
Executable file
@ -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()
|
47
test_regress/t/t_mod_automatic.v
Normal file
47
test_regress/t/t_mod_automatic.v
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user