SystemVerilog代码出现Latch inference问题,求ASIC流片解决方法
解决SystemVerilog中的锁存器推断问题
问题根源
你代码里的锁存器推断主要来自两个点:
e=m1[10]?(e+1):e;:组合逻辑中直接用e的当前值赋值,当m1[10]为低时,e需要保持原值,综合器会推断锁存器来维持这个状态,这是ASIC设计中要绝对避免的。m_f=m_f1:如果m_f被定义为reg类型且在组合逻辑环境中赋值(比如不在时序always块里),或者驱动路径存在未覆盖的分支,就会触发锁存器推断。另外,e的锁存器问题也可能连带导致工具误报m_f的问题。
修复方案
ASIC设计要求所有状态更新必须在时钟边沿触发,组合逻辑只负责纯组合运算,不能有状态保持逻辑。按以下方式修改代码:
方案1:移除冗余中间变量,全同步逻辑
// 组合逻辑生成m_f1(用wire类型,纯组合运算) wire [8:0] m_f1; assign m_f1 = m1[10] ? m1[9:1] : m1[8:0]; // 时序块处理所有状态更新和寄存器赋值 reg [5:0] e; // 对应c[14:9],位宽根据实际需求调整 reg [15:0] c; always@(posedge clk) begin // 同步更新e:仅在时钟边沿根据m1[10]状态自增或保持 e <= m1[10] ? e + 1'b1 : e; // 赋值c寄存器 c[15] <= s3; c[8:0] <= m_f1; // 直接使用组合逻辑输出,无需中间变量m_f c[14:9] <= e; end
方案2:保留m_f作为同步寄存器(如果需要)
如果m_f需要被时钟同步(比如跨时钟域或过滤毛刺),可以将m_f也放到时序块:
wire [8:0] m_f1; assign m_f1 = m1[10] ? m1[9:1] : m1[8:0]; reg [8:0] m_f; reg [5:0] e; reg [15:0] c; always@(posedge clk) begin m_f <= m_f1; // 同步m_f到时钟域 e <= m1[10] ? e + 1'b1 : e; c[15] <= s3; c[8:0] <= m_f; c[14:9] <= e; end
关键原则
- 组合逻辑(
assign或always@*)中,所有信号必须被所有输入组合赋值,绝对不能出现信号 = 条件 ? 新值 : 信号这种保持原值的写法。 - 所有状态类变量(需要保持值的变量)必须放到
always@(posedge clk)这类时序块中,用非阻塞赋值<=更新。
内容的提问来源于stack exchange,提问作者Adrikx
相关产品推荐
相关产品推荐

