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

用2选1MUX搭建4选1MUX输出延迟的原因及敏感列表修改疑问

为什么4选1 MUX用always @(sel)会出现延迟,改成@(*)就正常?

让我来拆解一下你遇到的这个问题,核心原因其实是手动编写的敏感列表不完整,导致仿真时组合逻辑的更新没有被及时触发。

先看原代码的问题所在

你的4选1 MUX模块里的上层always块是这么写的:

always @(sel) begin
if(sel[1] == 0) out <= w0;
else if (sel[1] == 1) out <= w1;
end

这个always块的作用是根据sel[1]选择下层两个2选1 MUX的输出w0或w1,赋值给out。但你只把sel加入了敏感列表——这意味着只有当sel整体发生变化时,这个always块才会执行。

但这里有个关键的点:w0和w1的更新是由sel[0]触发的(下层MUX的敏感列表是sel[0])。当sel[0]变化时,w0/w1会更新,但这个变化不会触发上层的always块(除非sel整体也变化了)。更糟的是,就算sel整体变化了,因为非阻塞赋值<=的特性,w0/w1的更新会在当前仿真周期的delta延迟后才完成,此时上层always块已经执行过了,读取的是w0/w1的旧值,自然就出现了1个时间单位的延迟。

@(*)为什么能解决问题?

@(*)是Verilog提供的自动敏感列表语法,它会自动扫描always块中所有在赋值右侧出现的变量,把它们全部加入敏感列表。对于你的这个always块来说,@(*)会自动包含sel[1]、w0、w1这三个变量。

这样一来,触发always块执行的条件就完整了:

  • 当sel(包括sel[0]或sel[1])变化时,会触发执行;
  • 当w0或w1更新时(下层MUX输出变化),也会立刻触发always块重新执行,此时就能读取到最新的w0/w1值,直接更新out,自然就不会有延迟了。

补充一个验证小技巧

如果你不想用@(*),也可以手动把所有依赖的变量都写进敏感列表,比如改成:

always @(sel[1], w0, w1) begin
if(sel[1] == 0) out <= w0;
else if (sel[1] == 1) out <= w1;
end

这样修改后,效果和@(*)完全一致,也能解决延迟问题——这也进一步印证了是敏感列表缺失变量导致的问题。

最后提个最佳实践

写组合逻辑的always块时,强烈推荐用@(*)(或者SystemVerilog里的always_comb),手动编写敏感列表很容易遗漏变量,不仅会导致仿真行为异常,甚至可能让综合工具生成不符合预期的电路。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:27:56