FPGA的设计中为什么避免使用锁存器

2024-01-09 10:20
文章标签 设计 使用 fpga 避免 存器

本文主要是介绍FPGA的设计中为什么避免使用锁存器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

  在FPGA的设计中,避免使用锁存器是几乎所有FPGA工程师的共识,Xilinx和Altera也在手册中提示大家要慎用锁存器,除非你明确知道你确实需要一个latch来解决问题。而且目前网上大多数文章都对锁存器有个误解,我们后面会详细说明。

  这篇文章,我们包含如下内容:

  1. 锁存器、触发器和寄存器的原理和区别,为什么锁存器不好?

  2. 什么样的代码会产生锁存器?

  3. 为什么锁存器依然存在于FPGA中?

锁存器、触发器和寄存器的原理和区别,为什么锁存器不好?

  锁存器、触发器和寄存器它们的英文分别为:Latch、Flip-Flop、Register。我们对这三个单词的翻译真的是非常直观,从名字就能大概猜出它们的含义。

锁存器
  1. 什么是锁存器?

  锁存器就是用来存储状态信息,就是将这个状态一直保持。锁存器对脉冲的电平敏感,也就是电平触发,在有效的电平下,锁存器处于使能状态,输出随着输入发生变化,此时它不锁存信号,就像一个缓冲器一样;在锁存器没有使能时,则数据被锁住,输入信号不起作用,此时输出一直为锁存的状态信息。我们常见的锁存器有SR锁存器、D锁存器、JK锁存器等。

  1. 锁存器的工作过程

  我们以最简单的D锁存器为例来说明锁存器的工作过程,D锁存器有3个接口,也可以认为是4个,因为输出的两个Q和\overline{Q}Q只是单纯的反向关系。

f9e2b495d0ddc073fcf96cf318f8c1a8.png
image

  其中D为输入信号,当E为高时,输出Q即为输入的D;当E为低时,Q保持E为高时的最后一次状态,也就是锁存过程。

56c82b5f363a6b29484631e64dfcc5b0.png
image
  1. 为什么锁存器不好?

  从上面的图中可以看出,锁存器对毛刺不敏感,很容易在信号上产生毛刺;而且也没有时钟信号,不容易进行静态时序分析。正是因为这两个原因,我们在FPGA设计时,尽量不用锁存器。

  当然,目前网上还有一种说法是FPGA中只有LUT和FF的资源,没有现成的Latch,所以如果要用Latch,需要更多的资源来搭出来。但这一观点,是错误的,我们后面会有专门的讲解。

触发器
  1. 什么是触发器

  触发器(Flip-Flop,简写为 FF),也叫双稳态门,又称双稳态触发器。在中国台湾及中国香港译作“正反器”,是一种具有两种稳态的用于储存的组件,可记录二进制数字信号“1”和“0”。

  FPGA工程师,对触发器再熟悉不过了,D触发器应该是我们平时写程序中用到最多的element。除了D触发器,常见的触发器还有T触发器、SR触发器、JK触发器等。触发器对脉冲边沿敏感,其状态只在时钟脉冲的上升沿或下降沿的瞬间改变。

  1. 触发器的工作过程

  我们以D触发器为例来说明触发器的工作过程,D触发器接口如下:

ff62f99116ed87769b30d28246ef7f76.png
image

  触发器只在时钟边沿时起作用,所以哪怕输入的信号中有毛刺,输出还是比较干净的。

a78f030689c938e088c3eea086330dce.png
image

  还有一点需要了解的是,FPGA中最小的单元是门电路,门电路又组成了锁存器,锁存器组成了寄存器。

寄存器

  用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果,它被广泛的用于各类数字系统和计算机中。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。工程中的寄存器一般按计算机中字节的位数设计,所以一般有8位寄存器、16位寄存器等。

什么样的代码会产生锁存器?

在组合逻辑中,如果条件描述不全就会容易产生Latch:

  1. if语句中缺少了else语句

  2. case语句中没有给出全部的情况。

也就是下面的情况:

always @ *
beginif(en==1)q <= d;
end
input [1:0]d;
always @ (d)
begincase(d)0:       q0 <= 1'b1;1:       q2 <= 1'b1;2:       q2 <= 1'b1;3:       q3 <= 1'b1;default: q4 <= 1'b1;
end

  这个前提是组合电路中,在时序电路的if语句中,及时没有else,也不会综合出Latch的。

  上面这两种写法容易出现在什么地方呢?最常见的就是状态机,我见过不少的FPGA工程师在写状态机时,case语句中没有给出变量的全部情况。

为什么锁存器依然存在于FPGA中?

  我们在前面说过网上有一种说法是:FPGA中只有LUT和FF的资源,没有现成的Latch,所以如果要用Latch,需要更多的资源来搭出来。这种说法是错误的,因为在Xilinx的FPGA中,6 系列之前的器件中都有Latch;6系列和7系列的FPGA中,一个Slice中有50%的storage element可以被配置为Latch或者Flip-Flop,另外一半只能被配置为Flip-Flop。比如7系列FPGA中,一个Slice中有8个Flip-Flop,如果被配置成了Latch,该Slice的另外4个Flip-Flop就不能用了。这样确实造成了资源的浪费。

084625224bdc512809b19731c835d0b9.png
image

在UltraScale的FPGA中,所有的storage element都可以被配置成Flip-Flop和Latch。

07a79d0af053a01e2aece972ab9e50a7.png
image

我们以下面的代码来说明Flip-Flop和Latch在Ultrascale的FPGA中Implementation后的结果。

Flip-Flop代码:

module FF_top(input              clk,input [3:0]        data_i,input              data_ie,  //enableoutput reg [3:0]   o_latch);always @ ( posedge clk )
beginif(data_ie)o_latch <= data_i;
end  endmodule

Latch代码:

module latch_top(input [7:0]        data_i,input              data_ie,  //enableoutput reg [7:0]   o_latch);always @ * 
beginif(data_ie)o_latch[3:0] <= data_i[3:0];
end  endmodule

Flip-Flop实现后的Schematic和Device如下:

a6cc45796892191e68ade2f3d3af4597.png
image

Latch实现后的Schematic和Device如下:

b510622a5ffadc7047a6d73cf91b98cc.png
image

可以看出,在使用Flip-Flop时,storage element被综合成了FDRE,也就是触发器;当使用Latch电路时,storage element被综合成了LDCE。

  所以,FPGA中没有Latch的说法在Xilinx的FPGA中是不对的。

  最后一个问题,既然Latch有这么多的问题,那为什么FPGA中还要保留?

  1. 首先就是因为FPGA电路的灵活性,保留Latch并不影响FPGA的资源,因为storage element可以直接被配置为Flip-Flop。

  2. 其次就是有些功能是必须要使用Latch的,比如很多处理器的接口就需要一个Latch来缓存数据或地址。

  最后要说明的一点是:锁存器虽然在FPGA中不怎么被使用,但在CPU中却很常见,因为锁存器比Flip-Flop快很多。

陪你度过深夜的2048小游戏,我们用FPGA实现它

基于FPGA的数字识别-实时视频处理的定点卷积神经网络实现

I3C的视频介绍

以太网的发展历史、演化过程以及工作基理

这篇关于FPGA的设计中为什么避免使用锁存器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/586785

相关文章

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

Conda与Python venv虚拟环境的区别与使用方法详解

《Conda与Pythonvenv虚拟环境的区别与使用方法详解》随着Python社区的成长,虚拟环境的概念和技术也在不断发展,:本文主要介绍Conda与Pythonvenv虚拟环境的区别与使用... 目录前言一、Conda 与 python venv 的核心区别1. Conda 的特点2. Python v

Spring Boot中WebSocket常用使用方法详解

《SpringBoot中WebSocket常用使用方法详解》本文从WebSocket的基础概念出发,详细介绍了SpringBoot集成WebSocket的步骤,并重点讲解了常用的使用方法,包括简单消... 目录一、WebSocket基础概念1.1 什么是WebSocket1.2 WebSocket与HTTP

C#中Guid类使用小结

《C#中Guid类使用小结》本文主要介绍了C#中Guid类用于生成和操作128位的唯一标识符,用于数据库主键及分布式系统,支持通过NewGuid、Parse等方法生成,感兴趣的可以了解一下... 目录前言一、什么是 Guid二、生成 Guid1. 使用 Guid.NewGuid() 方法2. 从字符串创建

Python使用python-can实现合并BLF文件

《Python使用python-can实现合并BLF文件》python-can库是Python生态中专注于CAN总线通信与数据处理的强大工具,本文将使用python-can为BLF文件合并提供高效灵活... 目录一、python-can 库:CAN 数据处理的利器二、BLF 文件合并核心代码解析1. 基础合

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Spring IoC 容器的使用详解(最新整理)

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean... 目录1. 应用分层2. IoC 的介绍3. IoC 容器的使用3.1. bean 的存储3.2. 方法注

Python内置函数之classmethod函数使用详解

《Python内置函数之classmethod函数使用详解》:本文主要介绍Python内置函数之classmethod函数使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录1. 类方法定义与基本语法2. 类方法 vs 实例方法 vs 静态方法3. 核心特性与用法(1编程客