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

编写D触发器(DFF)时出现锁存器(Latch)问题的排查求助

排查Verilog代码中的锁存器问题

你贴出的这段代码本身不会生成锁存器——两个always块都是边沿触发,且每个时钟沿都会给目标变量赋值,完全符合D触发器的综合规则:

  • 第一个always块:a1是由clk_a上升沿触发的D触发器,输入为in;
  • 第二个always块:b1是由clk_b上升沿触发的D触发器,输入为a1;out同样是clk_b上升沿触发的D触发器,输入为b1的上一拍值(非阻塞赋值<=是并行执行的,out<=b1取的是时钟沿到来前b1的旧值)。

团队检测到锁存器,大概率是以下原因导致:

  • 变量声明错误:如果a1/b1/out被错误声明为wire类型,却在always块里赋值——wire只能通过assign进行连续赋值,这种错误会让综合工具误生成锁存器(部分工具可能直接报语法错误)。正确做法是将这些变量声明为reg:

    reg a1, b1, out;
    
  • 综合工具误判或配置问题:部分旧版综合工具会把无复位的触发器误识别为锁存器,或者工具分析规则设置过于严格。建议查看工具的综合报告,定位被标记为锁存器的具体变量,针对性排查。

  • 未展示代码的影响:你只贴了部分代码,可能未展示的逻辑中存在组合逻辑未完全赋值的情况(比如if/case语句缺省分支),导致锁存器生成,团队误以为是这段代码的问题。

  • 概念混淆:a1由clk_a驱动,b1由clk_b采样a1属于跨时钟域场景,这只会带来亚稳态风险,不会生成锁存器,团队可能混淆了锁存器与跨时钟域问题的概念。

如果确认变量声明正确,且工具报告显示锁存器确实来自这段代码,可以尝试添加异步复位明确触发器行为,避免工具误判:

always@(posedge clk_a or negedge rst_n) begin
   if(!rst_n)
      a1 <= 1'b0;
   else
      a1 <= in;
end

always@(posedge clk_b or negedge rst_n) begin
   if(!rst_n) begin
      b1 <= 1'b0;
      out <= 1'b0;
   end else begin
      b1 <= a1;
      out <= b1;
   end
end

内容的提问来源于stack exchange,提问作者余昌翰

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:30:54