REVIEW
之前已经学习过: ROM:FPGA寄存器 Vivado IP核-CSDN博客 串口接收:Vivado 串口接收优化-CSDN博客 |
1. 今日摸鱼计划
RAM创建与测试 |
小梅哥视频: 21C_嵌入式块存储器RAM介绍_哔哩哔哩_bilibili 21D_嵌入式块存储器RAM实现和仿真_哔哩哔哩_bilibili 小梅哥教材: 02_【逻辑教程】基于HDL的FPGA逻辑设计与验证教程V3.4.pdf
14 IP 核使用之
RAM
|
2. RAM IP核配置
RAM(Random Access Memory): 它可以随时把数据写入到任何一指定地址的存储单元,也可以随时从任一指定地址读出数据。 其读写速度有时钟频率决定,主要用来存放程序以及程序执行过程中产生的数据运算结果等。 |
Distributed Memory Generator
生成的 ROM/RAM Core
占用的资源是
LUT
(查找表,查找表本质就是一个小的
RAM
)
Block Memory Generator
生成的
ROM/RAM Core
占用的资源是 Block Memory
(嵌入式的硬件
RAM
)
|
RAM
:单端口
RAM
、简单双端口
RAM 和真双端口 RAM
具体的差异我们可以通过依次选择,然后观察窗口左边
RAM 端口来进行对比
|
单端口
RAM
:读写一个时钟,读写不能同时进行。
|
简单双端口
RAM
:
相较单端口
RAM
,多出一个
PORTB,有两个时钟,可以同时读写,
PORTA
只能写数据,
PORTB
只能进行读数据。
|
真双端口
RAM
:
两个
PORT
,分别有自己的时钟、地址、输入/输出数据端口,两个端口均可进行读写操作。
|
写数据字节使能:
如果勾选,写使能信号会根据写数据的字节数生成对应的
bit
数据,
1
个字节对应
1bit
写使能,这里字节的大小可以设置为
8
或
9,当这里选择后,输入输出的数据的位宽就必须是
8
或
9 的整数倍,这里我们需要一个位宽为
8bit
的
RAM
,这里勾选
Write Enable
并设置字节大小为
8bit
。
|
算法类型
:有三种选项可选,最小面积、低功耗、固定原语。这里不过多讲解,需要了解更多的可以查阅
IP
手册,
IP
手册上面
42页开始有对这个详细的讲解。这里我们保持默认的最小面积选项即可。
|
操作模式设置:
有三个可选项,主要是针对在同时对同一地址进行读操作和写操作时,读出数据是写入的最新数据、该地址原来的数据、读数据不变化。
|
Write First 模式下的波形,如果仅读出数据而未发生数据的同时读写,则读出存储器以前存储的数据,如果发生数据的同时读写,读出数据为刚从数据总线送入的数据,而不考虑该地址以前存储的数据。
|
Read First 模式下的波形,同时对同一地址读写,读出数据为上次刚写入该地址以前的数据,忽略正在写数据这一事件对读出数据的影响。
|
No Change 模式下波形,读出的数据只有在进行读操作但未进行写操作时更新数据,在同时读写数据时,读出数据保持不变。
|
端口使能信号
类型设置,一个是一直使能,一个是通过一个
ENA 信号管脚控制,这里选择
Always Enable
。
|
端口B输出寄存器配置:
这里可以看下
RAM内部结构图,可以很清楚的看到
Primitives Output Register
是结构中的
1
处的寄存器,
Core Output Register 是结构图中
2
出的寄存器。
REGCEB Pin 是寄存器使能管脚,如果勾选,会有一个寄存器使能控制管脚用于控制寄存器的使能,如果不勾选寄存器就一直使能状态,这里就不勾选。
要得到更好的性能,将这里的两个寄存器都勾选。
|
端口 B 输出置位/复位设置
:
这里不创建置位
/
复位端口,需注意这里置位/复位并不复位
RAM
中的数据而是只复位寄存器上的值。
|
其它保持默认就OK |
最后看一看总的情况,信息包括使用的资源,
A
,
B 端口的地址位宽,以及端口
B Read Latency
为
3
个时钟周期。
|
Latentcy
指的是相对于某个时钟起始位的
1 个或多个时钟后数据才有效,一般以时钟为单位,这里表示的是时钟采集到读数据地址到数据有效的时间间隔,举例子说明:
这里之所以
Latency 等于 3
,是因为我们前面配置同时勾选了 Primitives Output Register
和
Core Output Register
,相当于数据打了两拍。
|
到这里
IP
设置就完成了,点击
OK
,点击
Generate
生成
IP
。
|
3. RAM 测试
`timescale 1ns/1ns module ram_tb(); //blk_mem_gen_0 是忘记改名字哩~ |
本测试,对RAM 地址0~31 写入127~96 然后从地址0~31依次读取其中的数值 |
这里可以看到读取时,会晚3个时钟周期 |
本次RAM读写都未配置使能ena enb 所以看起来很简单; (但是本摸鱼怪又觉得没有使能控制看着有点怪,后边再搞一下呗~) |
4. 带使能en的RAM
ram_tb |
`timescale 1ns/1ns module ram_tb(); |
#60; enb = 0; |
这个自己调试一下就会发现问题 (其实就是Latentcy ) |
本摸鱼怪还是行动力很强的嘛,桀桀桀~~~ |