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-elsecase语句)中没有处理所有可能的输入条件时,如果某个信号在某些条件下没有被明确赋值,则综合工具可能会推断出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

相关推荐
风_峰2 天前
Ubuntu Linux SD卡分区操作
嵌入式硬件·ubuntu·fpga开发
FPGA_Linuxer2 天前
FPGA 40 DAC线缆和光模块带光纤实现40G UDP差异
网络协议·fpga开发·udp
风_峰3 天前
Petalinux相关配置——ZYNQ通过eMMC启动
嵌入式硬件·ubuntu·fpga开发
风_峰3 天前
【ZYNQ开发篇】Petalinux和电脑端的静态ip地址配置
网络·嵌入式硬件·tcp/ip·ubuntu·fpga开发
碎碎思3 天前
一块板子,玩转 HDMI、USB、FPGA ——聊聊开源项目 HDMI2USB-Numato-Opsis
fpga开发
ooo-p3 天前
FPGA学习篇——Verilog学习Led灯的实现
学习·fpga开发
嵌入式-老费3 天前
Zynq开发实践(FPGA之选择开发板)
fpga开发
风_峰3 天前
PuTTY软件访问ZYNQ板卡的Linux系统
linux·服务器·嵌入式硬件·fpga开发
电子凉冰4 天前
FPGA入门-状态机
fpga开发
Aczone284 天前
硬件(十)IMX6ULL 中断与时钟配置
arm开发·单片机·嵌入式硬件·fpga开发