FPGA设计基础——RAM的应用(一)

FPGA设计基础——RAM的应用(一)

RAM是FPGA设计中使用非常广泛的一个组件,几乎每一个项目中都会用到。所以用好RAM也是FPGA设计的基本技能。本文主要从工程角度出发,阐述RAM在工程中的实际问题。

1、什么是RAM

RAM(random access memory),随机存储器,最基本的功能就是通过控制读写地址来实现RAM中存放数据的输出和写入。

2、RAM的特性

说明:本文中所指的RAM都是指FPGA中的RAM,且所举例均以Xilinx为例,Altera类似。

要利用好FPGA中的RAM,首先要了解RAM的一些属性,这是如何用好RAM的前提。本节将从RAM的分类、接口时序、配置、工作频率、读写冲突以及RAM在FPGA中的位置等方面说明。

(1)、RAM的分类

从RAM的组成资源来讲,RAM分成DRAM、BRAM、URAM。

DRAM:分布式ram,ram主要是由LUT和REG组成,适用于少量数据的存放,比如2Kbit(具体需要根据项目的实际情况而定)以下。

BRAM:就是我们常说的Block RAM,它是由FPGA中的硬core资源组成,RAMB18E2或者RAMB36E2,这种RAM是用的最多的一种。最主要的好处的是用了FPGA内部的硬core资源,性能相对好,也不会占用太多的LUT和REG。

URAM:这是xilinx高端器件中新增加的一种RAM,和BRAM类似,不同的是它的单位容量更大(288kbit),适合做更大的缓存。

从端口来讲,RAM又成为:

signal port ram:通过一个口来实现读和写;

simple dual port ram:简单双口ram,即一个口只读,一个口只写;

true dual port ram:真双口ram,有2个读口和2个写口;

从实际应用来讲,用的最多的还是简单双口ram,主要是用于数据的缓存,真双口ram在一写多读的表项设计中,使用相对会较多。

(2)、接口时序

RAM的接口时序主要是Native和AXI,其中Native类型的接口在FPGA的内部设计中用的比较多,接口相对简单,这里主要说明用的比较多的Native接口。

写接口时序如下图所示:

FPGA设计基础——RAM的应用(一)

主要的信号有写使能,写地址和写数据。数据a写入地址00、数据a1写入地址01……不同的配置下可能有其他的接口信号,但时了解这3个信号基本上就足够应用大部分的场景了。

在介绍读接口的时序前,先介绍一个基本的工程经验:为了提升性能,或者说提升FPGA工作的主频,FPGA RAM中输出的数据,在使用之前一定要用寄存器输出。从RAM中出来直接使用的话,组合逻辑会比较大,影响频率。那如何做寄存器输出呢?有2种方式:

方式A:IP catalog例化RAM的时候选择,如下图所示,有2个选择:

FPGA设计基础——RAM的应用(一)

这2个选择是什么意思了?那需要了解下RAM的基本结构,xilinx官网提供的资料PG058有说明,如下图所示:

FPGA设计基础——RAM的应用(一)

该图来自xilinx官网资料PG058


Block Memory本身带有2个寄存器,其中左边红色的寄存器位于Block RAM Primitives内部,右边的寄存器位于MUX选择之后。这2个寄存器分别对应IP catalog中的2个选择。加了寄存器有什么好处?这个后面说。这里需要说明的是,每加一个寄存器,输出的数据就要延迟一个时钟周期。如果2个寄存器都不加,BRAM的读接口时序如下图所示,其中a来之地址00,a1来之地址01……

FPGA设计基础——RAM的应用(一)


方式B:代码中直接对从RAM输出的数据打1拍或者2拍以后再使用,在接口时序上和方式A是一样的。

方式A和方式B,那种好?一般官方建议是采用方式A,但是作者在实际项目中采用B方式比较多,主要是时序清晰可控,效果也不错。

(3)、配置

在使用RAM之前,我们需要有一个概念,就是这个RAM的深度是多少?位宽是多少bit?这里只讨论读写位宽相同的情况。为什么呢?因为不同的宽度&深度的配置所需要的硬件资源是不一样的,在实际工程中,我们要寻找解决问题所需消耗的最小资源是多少。

在Xilinx的FPGA中,有RAM的基本单元为M18K和M36K,单位是bit,一个M36K包含了2个M18K。我们以M18K为例,如下表所示:

FPGA设计基础——RAM的应用(一)

出自xilinx官方文档PG058

换句话说,你需要的任何位宽&深度的RAM都是以上几种配置组合而成的。比如我需要一个宽度=4bit,深度=4K的ram,那么这个RAM需要一个M18K(不是M16K,因为带有ECC的功能),比如位宽=36bit,深度=512,也是需要消耗一个M18K。

在实际应用中,需要根据具体的设计,利用最小的资源灵活的把上述的各种规格拼接起来,来满足你的设计要求。如果自己实在搞不清楚需要多少RAM的时候,在用IP catalog例化RAM的时候,可以查看,比如16bit&3K深度的RAM,就需要3个M18K。

FPGA设计基础——RAM的应用(一)


FPGA设计基础——RAM的应用(一)


(4)、工作频率

这里说的工作频率是指设计中的RAM可以工作的时钟频率。我们知道一个系统的工作时钟频率取决于2个寄存器之间最长的逻辑时延。RAM内部本身是不包括寄存器的,所以工程上建议:1、写入RAM的写使能、写地址和写数据都用寄存器打一拍后再送到RAM的内部;2、读RAM的时候,读出的数据也要打一拍(具体如何打拍,参考(2)接口时序部分说明)以后再使用。也就是说,保证进入RAM的信号是寄存器输出,从RAM中输出的信号通过寄存器输出后再使用。

这一建议对于大多数的工程都是可以满足时序要求的。有的时候我们的工程频率不高,比如125M,器件也还行,RAM的输入和输出不采用寄存器输出,也不是完全不可以,具体问题需要具体分析。对于高频的工程,比如300M时钟以上,除了严格满足上述的建议外,最好还考虑下逻辑的布局。

(5)、读写冲突

读写冲突是指RAM在同一时刻同时读写同一个地址,那会存在一个问题,读出的值是新写入的值还是原来存放在RAM中的值了?供应商的RAM是考虑了读写冲突情况,比如例化RAM的时候会让你选择哪种模式:


FPGA设计基础——RAM的应用(一)


如果出现了读写冲突,选择如何告警。


FPGA设计基础——RAM的应用(一)

但是不提倡在使用RAM的时候出现读写冲突的情况。实际工程中,我们在使用一块RAM的时候,要从设计上做到先写后读,比如RAM作为缓存的时候,一定是先写入数据后,再读出数据。如果无法做到先读后写,比如表项的查询,那么我们要从设计上保证最终读出的数据是该地址写入的最新数据。具体的项目需要具体分析,总之我们尽量从设计上去规避读写冲突的出现。

(6)、RAM中FPGA中的位置

为什么要知道RAM在FPGA中的位置了?主要还是为了更好的利用RAM,先看看RAM在FPGA中的位置,如下图所示:


FPGA设计基础——RAM的应用(一)

红色框中就是RAM,RAM在FPGA内部呈“条”状,在芯片内部均衡分部,我们知道这个以后有2个好处:

第一:因为RAM的位置固定,从架构上限制了一些场景 ,比如一次要使用几十个上百个RAM的设计,可能就不是一个很好的设计,因为一次使用太多的RAM的逻辑占用的芯片面积太大,就不方便布局布线,那么时序也会相对较差。

第二:RAM不能全部用完,在资源评估的时候要预留一部分,预留多少,不同的芯片也会有不同,建议不超过80%,理由同上。

以上是关于RAM中的一些基本特性,RAM究竟如何用,敬请关注(RAM的应用(二)


分享到:


相關文章: