fpga系列 HDL:verilog latch在fpga中的作用 & 避免latch的常见做法

目录

Latch在FPGA中的作用

Quartus中有关latch的警告⚠

  • 如果代码中生成了Latch,会收到类似如下的警告:Warning (10240): Verilog HDL Always Construct warning at test.v(8): inferring latch(es) for variable "q", which holds its previous value in one or more paths through the always construct

避免Latch的常见做法

  • 当在组合逻辑(如if-else或case语句)中没有处理所有可能的输入条件时,如果某个信号在某些条件下没有被明确赋值,则综合工具可能会推断出Latch以维持该信号的前一状态。在一些复杂的组合逻辑中,存在从输出到输入的直接反馈路径也可能导致Latch的生成。

1. if-else 语句未覆盖所有条件

生成Latch的代码:
verilog 复制代码
module test (
    input wire sel,
    input wire in1,
    output reg out
);
    always @(*) begin
        if (sel == 1'b1) begin
            out = in1;
        end
        // 没有 else 分支
    end
endmodule


修复后的代码:
verilog 复制代码
module test (
    input wire sel,
    input wire in1,
    input wire in2, // 添加额外输入
    output reg out
);
    always @(*) begin
        out = in2; // 默认值
        if (sel == 1'b1) begin
            out = in1;
        end
    end
endmodule

2. case语句未覆盖所有分支

生成Latch的代码:
verilog 复制代码
module test (
    input wire [1:0] state,
    input wire in1,
    input wire in2,
    output reg out
);
    always @(*) begin
        case (state)
            2'b00: out = in1;
            2'b01: out = in2;
            // 没有 default 分支
        endcase
    end
endmodule
修复后的代码:
verilog 复制代码
module test (
    input wire [1:0] state,
    input wire in1,
    input wire in2,
    output reg out
);
    always @(*) begin
        case (state)
            2'b00: out = in1;
            2'b01: out = in2;
            default: out = 1'b0; // 添加默认值
        endcase
    end
endmodule

3. 组合逻辑中缺少默认赋值

生成Latch的代码:
verilog 复制代码
module test (
    input wire enable,
    input wire data_in,
    output reg out
);
    always @(*) begin
        if (enable) begin
            out = data_in;
        end
        // 没有 else 分支
    end
endmodule
修复后的代码:
verilog 复制代码
module test (
    input wire enable,
    input wire data_in,
    output reg out
);
    always @(*) begin
        out = 1'b0; // 默认值
        if (enable) begin
            out = data_in;
        end
    end
endmodule

4. 多路选择器中未处理所有输入

生成Latch的代码:
verilog 复制代码
module test (
    input wire [1:0] sel,
    input wire in1,
    input wire in2,
    input wire in3,
    output reg out
);
    always @(*) begin
        case (sel)
            2'b00: out = in1;
            2'b01: out = in2;
            2'b10: out = in3;
            // 没有处理 2'b11
        endcase
    end
endmodule
修复后的代码:
verilog 复制代码
module test (
    input wire [1:0] sel,
    input wire in1,
    input wire in2,
    input wire in3,
    output reg out
);
    always @(*) begin
        case (sel)
            2'b00: out = in1;
            2'b01: out = in2;
            2'b10: out = in3;
            default: out = 1'b0; // 添加默认值
        endcase
    end
endmodule

5. 部分条件未赋值

生成Latch的代码:
verilog 复制代码
module test (
    input wire condition1,
    input wire condition2,
    input wire in1,
    input wire in2,
    output reg out
);
    always @(*) begin
        if (condition1) begin
            out = in1;
        end else if (condition2) begin
            out = in2;
        end
        // 没有 else 分支
    end
endmodule
修复后的代码:
verilog 复制代码
module test (
    input wire condition1,
    input wire condition2,
    input wire in1,
    input wire in2,
    output reg out
);
    always @(*) begin
        out = 1'b0; // 默认值
        if (condition1) begin
            out = in1;
        end else if (condition2) begin
            out = in2;
        end
    end
endmodule

6. 反馈路径中的Latch

生成Latch的代码:
verilog 复制代码
module test (
    input wire reset,
    input wire enable,
    input wire d,
    output reg q
);
    always @(*) begin
        if (reset) begin
            q = 1'b0;
        end else if (enable) begin
            q = d;
        end
        // 没有 else 分支
    end
endmodule
修复后的代码:
verilog 复制代码
module test (
    input wire reset,
    input wire enable,
    input wire d,
    output reg q
);
    always @(*) begin
        q = 1'b0; // 默认值
        if (reset) begin
            q = 1'b0;
        end else if (enable) begin
            q = d;
        end
    end
endmodule

CG

相关推荐
花月mmc13 小时前
【FPGA】神经网络内容简介预告
嵌入式硬件·深度学习·神经网络·fpga开发
LabVIEW开发3 天前
LabVIEW FPGA 编程:少编译几次的办法(系列 04/05)
fpga开发·labview
cmc10283 天前
318.关于在ip内部封装PLL,MMCM的注意事项
fpga开发
LabVIEW开发3 天前
LabVIEW CompactRIO 编程模式怎么选(系列 02/05)
fpga开发·labview
FPGA小迷弟4 天前
FPGA 与千兆以太网校验和:从原理到 Verilog 实现
嵌入式硬件·fpga开发·无人机·ai编程·fpga
码农小韩4 天前
FPGA学习(二)——LED闪烁
fpga开发·verilog·fpga·led·组合逻辑·分频设计
9527华安5 天前
FPGA纯verilog实现DP视频接口,支持2K60帧分辨率,提供3套工程源码和技术支持
fpga开发·音视频·dp
ChaseVLSI6 天前
FPGA与ASIC的区别详解:内部结构、开发成本与适用场景,项目选型到底该选哪个
嵌入式硬件·fpga开发·硬件架构·硬件工程
9527华安6 天前
FPGA实现ARINC818总线协议,基于GT Transceivers Wizard高速收发器,提供7套工程源码和技术支持
fpga开发·transceivers·arinc818
小蘇的FPGA6 天前
fpga-wide-data-crc32
fpga开发