You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VHDL带超时上升沿等待语句的SystemVerilog等效实现问询

问题背景

用户需要将以下VHDL代码转换为等效的SystemVerilog代码:

process begin
    wait until rising_edge(mysig) for 1 us;
    if rising_edge(mysig) do_something() else do_something_else(); end if;
end process

用户已参考论坛用户@dave_59的思路实现了timed_re_wait任务,该任务用于模拟上述带超时的上升沿等待逻辑,目前仿真可正常运行,但不确定是否存在未考虑的边界情况,因此提出两个疑问:

  1. 该timed_re_wait任务的实现是否正确?
  2. 调用该任务后,如何检测当前mysig是否出现了上升沿?如果无法直接检测,是否只能通过让任务输出expired标志位来进行后续判断?
解答

一、timed_re_wait任务的正确性与边界检查

要确认任务实现是否正确,核心是看它是否完全复现VHDL原逻辑的行为:在1微秒窗口内等待mysig的上升沿,超时则终止等待。需要重点验证以下边界场景:

  • 调用任务时mysig已处于上升沿触发状态:比如调用前mysig刚完成从0到1的跳变,此时VHDL会直接识别上升沿,任务需要立即返回,不能进入超时等待。
  • 超时瞬间恰好出现上升沿:当1微秒超时的同一仿真时刻,mysig发生上升沿,此时应判定为捕获到上升沿,而非超时,对应原逻辑执行do_something()。
  • 任务重复调用的状态独立性:多次调用任务时,内部的时序事件(如超时定时器)不能残留上一次调用的状态,避免干扰后续逻辑。

如果你的任务实现覆盖了以上场景,且仿真验证通过,那么基本可以认为是正确的。

二、调用任务后检测上升沿的方案

在SystemVerilog中,调用任务后无法直接用rising_edge(mysig)判断任务等待窗口内是否出现过上升沿——因为任务执行期间的时序事件已经结束,当前时刻的rising_edge检测只能反映当下的信号状态,无法对应之前的等待周期。

因此,最可靠的方式是让timed_re_wait任务输出一个expired标志位:

  • 若expired为0,说明超时前捕获到了mysig的上升沿,后续执行do_something();
  • 若expired为1,说明等待超时,执行do_something_else()。

典型的任务实现示例:

task timed_re_wait(input logic mysig, input time timeout, output bit expired);
    fork
        begin
            @(posedge mysig); // 等待上升沿触发
            expired = 1'b0;
        end
        begin
            #timeout; // 等待超时时间
            expired = 1'b1;
        end
    join_any
    disable fork; // 终止未完成的分支
endtask

调用时直接根据expired值分支处理:

bit expired_flag;
timed_re_wait(mysig, 1us, expired_flag);
if (!expired_flag) begin
    do_something();
end else begin
    do_something_else();
end

这种方式完全匹配VHDL原逻辑的行为,也是SystemVerilog中实现带超时事件等待的标准做法,不存在歧义。

内容的提问来源于stack exchange,提问作者Craig

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:12:20