Allow pure functions in sensitivity lists (#6393)
Signed-off-by: Krzysztof Bieganski <kbieganski@antmicro.com>
This commit is contained in:
parent
1923d23cff
commit
5349b51e71
|
|
@ -746,7 +746,9 @@ const TriggerKit createTriggers(AstNetlist* netlistp, AstCFunc* const initFuncp,
|
||||||
ss << "@(";
|
ss << "@(";
|
||||||
V3EmitV::verilogForTree(senItemp, ss);
|
V3EmitV::verilogForTree(senItemp, ss);
|
||||||
ss << ")";
|
ss << ")";
|
||||||
addDebug(triggerNumber, VString::quoteBackslash(ss.str()));
|
std::string desc = VString::quoteBackslash(ss.str());
|
||||||
|
desc = VString::replaceSubstr(desc, "\n", "\\n");
|
||||||
|
addDebug(triggerNumber, desc);
|
||||||
|
|
||||||
//
|
//
|
||||||
++triggerNumber;
|
++triggerNumber;
|
||||||
|
|
|
||||||
|
|
@ -1458,8 +1458,9 @@ class TaskVisitor final : public VNVisitor {
|
||||||
UASSERT_OBJ(!m_insStmtp, nodep, "Didn't finish out last statement");
|
UASSERT_OBJ(!m_insStmtp, nodep, "Didn't finish out last statement");
|
||||||
}
|
}
|
||||||
void visit(AstNodeFTaskRef* nodep) override {
|
void visit(AstNodeFTaskRef* nodep) override {
|
||||||
if (m_inSensesp) {
|
if (m_inSensesp && !nodep->isPure()) {
|
||||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: function calls in sensitivity lists");
|
nodep->v3warn(E_UNSUPPORTED,
|
||||||
|
"Unsupported: Impure function calls in sensitivity lists");
|
||||||
nodep->taskp(nullptr); // So V3Broken doesn't complain
|
nodep->taskp(nullptr); // So V3Broken doesn't complain
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,8 @@ endmodule
|
||||||
`EXPR_TEST(queue, 0, (input int q[$]), q[0])
|
`EXPR_TEST(queue, 0, (input int q[$]), q[0])
|
||||||
`EXPR_TEST(queue_mul, 0, (input int q[$], int i), q[0]*i)
|
`EXPR_TEST(queue_mul, 0, (input int q[$], int i), q[0]*i)
|
||||||
|
|
||||||
`ifdef UNSUP
|
|
||||||
function int id(int x); return x; endfunction
|
function int id(int x); return x; endfunction
|
||||||
`EXPR_TEST(func, 0, (input int cyc), id(cyc))
|
`EXPR_TEST(func, 0, (input int cyc), id(cyc))
|
||||||
`endif
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Class tests (special case as V3Width doesn't always properly handle
|
// Class tests (special case as V3Width doesn't always properly handle
|
||||||
|
|
@ -78,27 +76,25 @@ endmodule
|
||||||
|
|
||||||
`CLASS_TEST(class, obj.k)
|
`CLASS_TEST(class, obj.k)
|
||||||
|
|
||||||
`ifdef UNSUP
|
|
||||||
`CLASS_TEST(method, obj.get_k())
|
`CLASS_TEST(method, obj.get_k())
|
||||||
`endif
|
`endif
|
||||||
`endif
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// $c test has to be written out explicitly as the STRINGIFY macro can't handle it
|
// $c test has to be written out explicitly as the STRINGIFY macro can't handle it
|
||||||
//
|
//
|
||||||
module t_cstmt;
|
module t_cstmt;
|
||||||
logic last = 0;
|
logic last = 0;
|
||||||
always @($c("vlSelf->clk")) begin
|
always @($c("vlSymsp->TOP.clk")) begin
|
||||||
if ($time > 0 && logic'($c("vlSelf->clk")) == last) $stop;
|
if ($time > 0 && logic'($c("vlSymsp->TOP.clk")) == last) $stop;
|
||||||
last <= logic'($c("vlSelf->clk"));
|
last <= logic'($c("vlSymsp->TOP.clk"));
|
||||||
end
|
end
|
||||||
always @(posedge $c("vlSelf->clk")) begin
|
always @(posedge $c("vlSymsp->TOP.clk")) begin
|
||||||
`WRITE_VERBOSE(("[%0t] cstmt [posedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last));
|
`WRITE_VERBOSE(("[%0t] cstmt [posedge] $c(\"vlSymsp->TOP.clk\")=%0b, last=%b\n", $time, $c("vlSymsp->TOP.clk"), last));
|
||||||
if ($time > 0 && (~logic'($c("vlSelf->clk")) || last)) $stop;
|
if ($time > 0 && (~logic'($c("vlSymsp->TOP.clk")) || last)) $stop;
|
||||||
end
|
end
|
||||||
always @(negedge $c("vlSelf->clk")) begin
|
always @(negedge $c("vlSymsp->TOP.clk")) begin
|
||||||
`WRITE_VERBOSE(("[%0t] cstmt [negedge] $c(\"vlSelf->clk\")=%0b, last=%b\n", $time, $c("vlSelf->clk"), last));
|
`WRITE_VERBOSE(("[%0t] cstmt [negedge] $c(\"vlSymsp->TOP.clk\")=%0b, last=%b\n", $time, $c("vlSymsp->TOP.clk"), last));
|
||||||
if ($time > 0 && (logic'($c("vlSelf->clk")) || !last)) $stop;
|
if ($time > 0 && (logic'($c("vlSymsp->TOP.clk")) || !last)) $stop;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
@ -129,17 +125,13 @@ module t(/*AUTOARG*/
|
||||||
t_queue u_queue(.*);
|
t_queue u_queue(.*);
|
||||||
t_queue_mul u_queue_mul(.*);
|
t_queue_mul u_queue_mul(.*);
|
||||||
|
|
||||||
`ifdef UNSUP
|
|
||||||
t_func u_func(.*);
|
t_func u_func(.*);
|
||||||
`endif
|
|
||||||
|
|
||||||
int k;
|
int k;
|
||||||
assign k = i + j;
|
assign k = i + j;
|
||||||
`ifndef NO_CLASS
|
`ifndef NO_CLASS
|
||||||
t_class u_class(.*);
|
t_class u_class(.*);
|
||||||
`ifdef UNSUP
|
|
||||||
t_method u_method(.*);
|
t_method u_method(.*);
|
||||||
`endif
|
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
t_cstmt u_cstmt();
|
t_cstmt u_cstmt();
|
||||||
|
|
|
||||||
|
|
@ -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')
|
||||||
|
test.top_filename = 't_event_control_expr.v'
|
||||||
|
|
||||||
|
test.compile(
|
||||||
|
# do not test classes for multithreaded, as V3InstrCount doesn't handle MemberSel
|
||||||
|
verilator_flags2=(['-fno-inline'] + ['-DNO_CLASS'] if test.vltmt else []))
|
||||||
|
|
||||||
|
test.execute()
|
||||||
|
|
||||||
|
test.passes()
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
%Error-UNSUPPORTED: t/t_event_control_expr.v:55:13: Unsupported: function calls in sensitivity lists
|
%Error-UNSUPPORTED: t/t_event_control_expr_unsup.v:15:21: Unsupported: Impure function calls in sensitivity lists
|
||||||
55 | always @(id(cyc)) begin
|
15 | always @(posedge foo());
|
||||||
| ^~
|
| ^~~
|
||||||
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
|
||||||
%Error-UNSUPPORTED: t/t_event_control_expr.v:82:17: Unsupported: function calls in sensitivity lists
|
|
||||||
: ... note: In instance 't.u_method'
|
|
||||||
82 | always @(obj.get_k()) begin
|
|
||||||
| ^~~~~
|
|
||||||
%Error: Exiting due to
|
%Error: Exiting due to
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
import vltest_bootstrap
|
import vltest_bootstrap
|
||||||
|
|
||||||
test.scenarios('vlt') # no vltmt, as AstMemberSel is unhandled in V3InstrCount
|
test.scenarios('vlt') # no vltmt, as AstMemberSel is unhandled in V3InstrCount
|
||||||
test.top_filename = "t_event_control_expr.v"
|
|
||||||
|
|
||||||
test.lint(verilator_flags2=['-DUNSUP'], fails=True, expect_filename=test.golden_filename)
|
test.lint(fails=True, expect_filename=test.golden_filename)
|
||||||
|
|
||||||
test.passes()
|
test.passes()
|
||||||
|
|
|
||||||
|
|
@ -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, 2025 by Antmicro.
|
||||||
|
// SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
module t;
|
||||||
|
int x;
|
||||||
|
|
||||||
|
function bit foo;
|
||||||
|
x += 1;
|
||||||
|
return bit'(x % 2);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
always @(posedge foo());
|
||||||
|
|
||||||
|
endmodule
|
||||||
Loading…
Reference in New Issue