常见的FPGA存储器有3种,RAM( 随机访问内存)ROM(只读存储器)FIFO(先入先出)
这三种存储器的区别如下:
其中RAM通常都是在掉电之后就丢失数据,ROM在系统停止供电的时候仍然可以保持数据
可以向RAM和ROM中的任意位置写入数据,也可以读取任意的位置的数据
而FIFO的数据先入先出,先进去的数据先出来,只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
这三种存储器的应用场合:
RAM和ROM常用于存储指令或者中间的数据
FIFO常用于数据传输通道中用于缓存数据,避免数据丢失,如不同速率时钟模块间的数据传输就需要用到异步FIFO
目录
RAM
所谓"随机存取",指的是当存储器中的数据被读取或写入时,所需要的时间与这段信息所在的位置或所写入的位置无关
1、RAM种类
(1)RAM:随机访问内存
随机访问内存(RAM)相当于PC机上的移动存储,用来存储和保存数据的。在任何时候都可以读写,RAM通常用作操作系统或其他正在运行的程序的临时存储介质(可称作系统内存)。不过,当电源关闭时时RAM不能保留数据,如果需要保存数据,就必须把它们写入到一个长期的存储器中(例如硬盘)。正因为如此,有时也将RAM称作"可变存储器"。RAM内存可以进一步分为静态RAM(SRAM)和动态内存(DRAM)两大类。
(2)SRAM:静态随机存取存储器
静态随机存取存储器(Static Random-Access Memory,SRAM)是随机存取存储器的一种。所谓的“静态”,是指这种存储器只要保持通电,里面储存的数据就可以恒常保持。相对之下,动态随机存取存储器(DRAM)里面所储存的数据就需要周期性地更新。然而,当电力供应停止时,SRAM储存的数据还是会消失(被称为volatile memory),这与在断电后还能储存资料的ROM或闪存是不同的。
(3)DRAM:动态随机存取存储器
SRAM不需要刷新电路即能保存它内部存储的数据。而DRAM(Dynamic Random Access Memory)每隔一段时间,要刷新充电一次,否则内部的数据即会消失,因此SRAM具有较高的性能,但是SRAM也有它的缺点,即它的集成度较低,功耗较DRAM大 ,相同容量的DRAM内存可以设计为较小的体积,但是SRAM却需要很大的体积。同样面积的硅片可以做出更大容量的DRAM,因此SRAM显得更贵。
2、RAM端口
接下来我们看一下怎么调用RAM
在IP核中搜索RAMs,选择Block Memory Generator
选择端口模式
1.单端口RAM:
只有一组数据线和地址线,所以不能同时进行读写操作。即同一时刻要么读要么写。
2.真双口RAM:
真双口RAM 是在一个SRAM 存储器上具有两套完全独立的数据线、地址线和读写控制线,并允许两个独立的系统同时对该存储器进行随机性的访问。即读写可同时进行。而单口RAM只有一组数据线与地址线,因此读写不能同时进行。
真双口RAM有两组数据线与地址线,能同时进行两个端口读,能同时进行两个端口写,能同时一个端口读同时另一个端口写
3.伪双口RAM:
一个端口只读,另一个端口只写;而真双口RAM两个端口都可以读写
3.单端口读写RAM
1 选择简单双口模式(伪双口)
2 修改AB口的数据宽度和深度:
width 宽度 对应数据位宽:dina[ : ]和dout[ : ]
depth 深度 对应地址深度:addr[ : ]
3 选择“写优先”还是“读优先”还是“no change”
写优先:
读优先:
no change:
这一块主要是在真的双端口RAM里面,真的双端口RAM里面A口和B口都可以独立的去读写RAM里面的数据,写优先是指在RAM的一端写入数据时此端口的下一个输出为上一次写入的数值,读优先则相反输出为RAM原来存的数据,No chance为输出保持不变。
最后我们可以看一下我们创建的RAM的管脚:
RAM 的管脚如下:
addra是a 的地址深度;addrb是b的地址深度;
clka是a的时钟信号;clkb是b的时钟信号;
dina是a输入数据;doutb是b输出数据;
ena是a使能信号;enb是b使能信号;
wea是读/写使能(wea=0读,wea=1写)
RAM inst_RAM
(
.clka (clk_25m), // input wire clka
.ena (ena), // input wire ena
.wea (wea), // input wire [0 : 0] wea
.addra (addra), // input wire [4 : 0] addra
.dina (dina), // input wire [3 : 0] dina
.clkb (clk_25m), // input wire clkb
.enb (enb), // input wire enb
.addrb (addrb), // input wire [4 : 0] addrb
.doutb (doutb) // output wire [3 : 0] doutb
);
最后我们把IP核例化进需要用里面参数的程序即可
4.双端口读写RAM
1.选择真双端口
2.修改数据位宽和地址深度
3. 把下面的对钩去掉,否则RAM会延迟2个时钟
我们可以看一下生成的RAM管脚:
和单口RAM不同的是,双口RAM的b端口也有读/写使能web(web=0读,web=1写)
ROM
ROM和RAM的创建相似,在种类里面选择可以选择单口ROM和双口ROM
FIFO
1.在IP核搜索FIFOs,选择FIFO Generator
2.修改FIFO的参数
两种读模式的主要区别是:
当选择Standard模式的时候,在读使能信号有效的下一个周期才能读出第一个有效的数据;
实际的读写深度会比写入的读写深度少1
当选择FWFT模式的时候,在读使能信号有效的第一个周期就能能读出第一个有效的数据; 这是因为在这种模式下,FIFO提前把数据已经准备到了数据输出总线上,等待读使能有效就输出到数据输出端口(组合逻辑),但在这种模式下,valid信号将会在复位后就保持有效
实际的读写深度会比写入的读写深度多1
3.选择FIFO类型
可以用块RAM、分布式RAM,移位寄存器和内嵌FIFO来实现FIFO。最常用的是block RAM和distribute RAM
block RAM是FPGA中定制的ram资源,而distribute RAM则是由LUT构成的RAM资源,当FIFO较大时应选择block RAM,当FIFO较小时,选择distribute RAM.
common(同步)FIFO的输入和输出在一个时钟下(只有一个clk)
independent (异步)FIFO的输入和输出在不同时钟下(wr_clk 和rd_clk)
4.添加几乎满,几乎空引脚
为了防止数据在FIFO中溢出或者丢失,可以将几乎满和几乎空标志作为FIFO已经满和空的标志
最后我们可以看一下生成的FIFIO引脚:
这是一个异步FIFO,wr_clk为写时钟;rd_clk为读时钟
din[3:0]为写入4位二进制数据;dout[3:0]为读出4位二进制数据
almost full和full;almost empty和empty是空满标志
wr_en为写使能,高电平有效;rd_en为读使能,高电平有效
由于FIFO复位需要时间,因此在wr_rst_busy和rd_rst_busy为高电平时不可以输入输出数据
————————————————
参考文献:
https://blog.csdn.net/yh13572438258/article/details/121675750