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

既然always_ff等价于always @(posedge clk),为何还要写前者?

关于SystemVerilog中always_ff与always @(posedge clk)的疑问解答
  • 为什么要写always_ff @(posedge clk)而不是只用always @(posedge clk)?
    always_ff是SystemVerilog新增的显式时序逻辑块声明,和传统的always @(posedge clk)相比,它能让综合、lint工具做更严格的语法检查:

    • 强制这个块只能用于时序逻辑,不允许在里面写组合逻辑的违规操作(比如在块内修改输入信号、用阻塞赋值实现组合逻辑等);
    • 敏感列表只能包含时钟(可选加异步复位),避免你不小心写错敏感列表(比如漏加复位信号)却没被工具及时发现。
      简单说,always_ff就是给工具和读代码的人明确划界:“这块是纯时序逻辑,别乱搞”,从编码层面减少人为失误。
  • 为什么要区分不同的always结构?
    SystemVerilog把always块拆成always_ff(时序)、always_comb(组合)、always_latch(锁存器),核心原因有两个:

    1. 可读性拉满:别人看代码不用去翻敏感列表和赋值方式,一眼就知道这个块的逻辑类型;
    2. 工具检查更精准:比如always_comb会自动推断完整的敏感列表,还会检查是否有意外生成锁存器的风险;always_latch则专门用于声明锁存器逻辑,避免工具误优化。
      传统的always块是隐式的,工具和人都得自己判断逻辑类型,很容易埋下bug。
  • 有没有always @(posedge clk)不生成触发器的情况?
    有,而且大多是不规范写法导致的:

    • 比如在时钟敏感块里直接把输入信号组合后赋值给输出,完全没有状态存储需求——比如:
      always @(posedge clk) begin
          out = in_a & in_b;
      end
      
      这种逻辑里,out的值只依赖当前时钟沿的输入,不需要保留上一周期的状态,综合工具会直接优化成组合逻辑,不会生成触发器,但这属于错误的编码方式,时序块的设计初衷就是用来做状态存储。
    • 另外,如果逻辑被工具完全优化掉(比如所有输入都是常量,输出结果固定),对应的触发器也会被删掉。
  • 这在ASIC设计中比FPGA更重要吗?
    是的,而且重要得多。ASIC流片成本极高,一旦出问题损失巨大,所以设计阶段的每一步都要尽可能规避风险。always_ff这类显式声明能让lint、综合工具更早发现逻辑错误(比如把组合逻辑塞进时序块),避免后期仿真或流片才暴露问题。
    FPGA迭代成本低,即使写错了也能重新烧写,但规范的编码风格依然推荐用always_ff,既能减少bug,也能让代码更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 13:34:56