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 ) |
本摸鱼怪还是行动力很强的嘛,桀桀桀~~~ |