SystemVerilog wait调用task报Cross-module reference错误如何解决?
报错根本原因
你遇到的编译错误核心是违反了SystemVerilog的两个基础语法规则:
- wait语句后的表达式仅支持对可立即求值的对象进行判断,你在表达式中直接调用
run()时,编译器会默认期望run()是有返回值的function,但你定义的run是task,task本身没有返回值,无法参与== 1这类比较运算,因此触发了"Function is expected, but actual target is not a function"的报错。 - 即便你把
run强行改为function也无法实现需求:SystemVerilog规定function必须在零仿真时间内执行完成,内部不允许使用#、@、wait等阻塞延时语句,你的延时3ns赋值的逻辑无法在function中实现。
修正方案
你的核心需求是启动带延时的run任务后,等待它给t2赋值为1再往下执行,只需要将run任务放到后台异步启动,再直接监听t2的值即可,修正后的完整代码如下:
class cl; task run(output bit t); $display("time=%0t , t=%0b",$realtime, t); #1; $display("time=%0t , t=%0b",$realtime, t); #2; t = 1; $display("time=%0t , t=%0b",$realtime, t); endtask endclass class c2 extends cl; bit t2; task run1(); // 用fork join_none后台启动run任务,不阻塞当前线程的wait判断 fork run(t2); join_none // 直接监听t2的取值,符合wait语句的语法要求 wait(t2 == 1); $display("t2 working t2=%0b time = %0t", t2, $realtime); endtask endclass module tmp; c2 c2_h=new; initial begin c2_h.run1(); $display("test msg"); end endmodule
运行结果验证
修正后代码的仿真输出完全符合你的预期:
time=0 , t=0 time=1 , t=0 time=3 , t=1 t2 working t2=1 time = 3 test msg
wait语句从0ns开始生效,到3nst2被赋值为1时自动结束等待,后续打印逻辑正常执行。
内容的提问来源于stack exchange,提问作者user_rak
相关产品推荐
相关产品推荐

