1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-301505-1-1.html 4)对正点原子FPGA感兴趣的同学可以加群讨论:994244016 5)关注正点原子公众号,获取最新资料更新
RAM的英文全称是Random Access Memory,即随机存取存储器,它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度是由时钟频率决定的。RAM主要用来存放程序及程序执行过程中产生的中间数据、运算结果等。本章我们将对Vivado软件生成的RAM IP核进行读写测试,并向大家介绍Xilinx RAM IP核的使用方法。 本章包括以下几个部分: 1.1 RAM IP核简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证
1.1 RAM IP核简介Xilinx 7系列器件具有嵌入式存储器结构,满足了设计对片上存储器的需求。嵌入式存储器结构由一列列BRAM(块RAM)存储器模块组成,通过对这些BRAM存储器模块进行配置,可以实现各种存储器的功能,例如:RAM、移位寄存器、ROM以及FIFO缓冲器。 Vivado软件自带了BMG IP核(Block Memory Generator,块RAM生成器),可以配置成RAM或者ROM。这两者的区别是RAM是一种随机存取存储器,不仅仅可以存储数据,同时支持对存储的数据进行修改;而ROM是一种只读存储器,也就是说,在正常工作时只能读出数据,而不能写入数据。需要注意的是,配置成RAM或者ROM使用的资源都是FPGA内部的BRAM,只不过配置成ROM时只用到了嵌入式BRAM的读数据端口。本章我们主要介绍通过BRAM IP核配置成RAM的使用方法。 Xilinx 7系列器件内部的BRAM全部是真双端口RAM(True Dual-Port ram,TDP),这两个端口都可以独立地对BRAM进行读/写。但也可以被配置成伪双端口RAM(Simple Dual-Port ram,SDP)(有两个端口,但是其中一个只能读,另一个只能写)或单端口RAM(只有一个端口,读/写只能通过这一个端口来进行)。单端口RAM只有一组数据总线、地址总线、时钟信号以及其他控制信号,而双端口RAM具有两组数据总线、地址总线、时钟信号以及其他控制信号。有关BRAM的更详细的介绍,请读者参阅Xilinx官方的手册文档“UG473,7 Series FPGAs Memory Resources User Guide”。 单端口RAM类型和双端口RAM类型在操作上都是一样的,我们只要学会了单端口RAM的使用,那么学习双端口RAM的读写操作也是非常容易的。本章我们以配置成单端口RAM为例进行讲解。 BMG IP核配置成单端口RAM的框图如下图所示。
图 7.5.13.1 单端口RAM框图 各个端口的功能描述如下: DINA:RAM端口A写数据信号。 ADDRA:RAM端口A读写地址信号,对于单端口RAM来说,读地址和写地址共用同该地址线。 WEA:RAM端口A写使能信号,高电平表示向RAM中写入数据,低电平表示从RAM中读出数据。 ENA:端口A的使能信号,高电平表示使能端口A,低电平表示端口A被禁止,禁止后端口A上的读写操作都会变成无效。另外ENA信号是可选的,当取消该使能信号后,RAM会一直处于有效状态。 RSTA:RAM端口A复位信号,可配置成高电平或者低电平复位,该复位信号是一个可选信号。 REGCEA:RAM端口A输出寄存器使能信号,当REGCEA为高电平时,DOUTA保持最后一次输出的数据,REGCEA同样是一个可选信号。 CLKA:RAM端口A的时钟信号。 DOUTA:RAM端口A读出的数据。 1.2 实验任务 本节实验任务是使用Xilinx BMG IP核,配置成一个单端口的RAM,然后对RAM进行读写操作,通过在Vivado自带的仿真器中观察波形是否正确,最后将设计下载到领航者Zynq开发板中,并使用ILA对其进行在线调试观察。 1.3 硬件设计 本章实验只用到了输入的时钟信号和按键复位信号,没有用到其它硬件外设,各端口信号的管脚分配如下表所示: 表 14.3.1 IP核之RAM实验管脚分配 信号名 方向 管脚 端口说明 电平标准 sys_clk input U18 系统时钟,50Mhz LVCMOS33 sys_rst_n input N16 系统复位,低电平有效,位于底板上 LVCMOS33 对应的XDC约束语句如下所示:
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
1.4 程序设计 首先在Vivado软件中创建一个名为ip_ram的工程,工程创建完成后,在Vivado软件的左侧“Flow Navigator”栏中单击“IP Catalog”,如下图所示。
图 7.5.13.1 点击“IP Catalog” 在“IP Catalog”窗口的搜索框中输入“Block Memory”,出现唯一匹配的“Block Memory Generator”,如下图所示(图中出现的两个IP核为同一个BMG IP核)。
图 7.5.13.2 搜索框中输入“Block Memory” 双击“Block Memory Generator”后弹出IP核的配置界面,接下来对BMG IP核进行配置,“Basic”选项页配置界面如下图所示。
图 7.5.13.3 “Basic”选项页配置 Component Name:设置该IP核的名称,这里保持默认即可。 Interface Type:RAM接口总线。这里保持默认,选择Native接口类型(标准RAM接口总线); Memory Type:存储器类型。可配置成Single Port RAM(单端口RAM)、Simple Dual Port RAM(伪双端口RAM)、True Dual Port RAM(真双端口RAM)、Single Port ROM(单端口ROM)和Dual Port ROM(双端口ROM),这里选择Single Port RAM,即配置成单端口RAM。 ECC Options:Error Correction Capability,纠错能力选项,单端口RAM不支持ECC。 Write Enable:字节写使能选项,勾中后可以单独将数据的某个字节写入RAM中,这里不使能。 Algorithm Options:算法选项。可选择Minimum Area(最小面积)、Low Power(低功耗)和Fixed Primitives(固定的原语),这里选择默认的Minimum Area。 接下来切换至“Port A”选项页,设置端口A的参数,该页面配置如下:
图 7.5.13.4 “Port A Options”选项页配置 Write Width:端口A写数据位宽,单位Bit,这里设置成8。 Read Width:端口A读数据位宽,一般和写数据位宽保持一致,设置成8。 Write Depth:写深度,这里设置成32,即RAM所能访问的地址范围为0-31。 Read Depth:读深度,默认和写深度保持一致。 Operating Mode:RAM读写操作模式。共分为三种模式,分别是Write First(写优先模式)、Read First(读优先模式)和No Change(不变模式)。写优先模式指数据先写入RAM中,然后在下一个时钟输出该数据;读优先模式指数据先写入RAM中,同时输出RAM中同地址的上一次数据;不变模式指读写分开操作,不能同时进行读写,这里选择No Change模式。 Enable Port Type:使能端口类型。Use ENA pin(添加使能端口A信号);Always Enabled(取消使能信号,端口A一直处于使能状态),这里选择默认的Use ENA pin。 Port A Optional Output Register:端口A输出寄存器选项。其中“Primitives Output Register”默认是选中状态,作用是打开BRAM内部位于输出数据总线之后的输出流水线寄存器,虽然在一般设计中为了改善时序性能会保持此选项的默认勾选状态,但是这会使得BRAM输出的数据延迟一拍,这不利于我们在Vivado的ILA调试窗口中直观清晰地观察信号;而且在本实验中我们仅仅是把BRAM的数据输出总线连接到了ILA的探针端口上来进行观察,除此之外数据输出总线没有别的负载,不会带来难以满足的时序路径,因此这里取消勾选。 Port A Output Reset Options:RAM复位信号选项,这里不添加复位信号,保持默认即可。 另外,需要注意的是,下面的“Primitives Output Register”默认是选中状态的,此选项的作用是打开块RAM内部的位于输出数据总线之后的输出流水线寄存器,虽然在一般设计中为了改善时序性能会保持此选项的默认勾选状态,但是这会使得块RAM输出的数据延迟一拍,这不利于我们在Vivado的ILA调试窗口中直观清晰地观察信号;而且在本实验中我们仅仅是把块RAM的数据输出总线连接到了ILA的探针端口上来进行观察,除此之外数据输出总线没有别的负载,不会带来难以满足的时序路径。 接下来的“Other Options”选项页用于设置RAM的初始值等,本次实验不需要设置,直接保持默认即可。 最后一个是“Summary”选项页,该页面显示了存储器的类型,消耗的BRAM资源等,我们直接点击“OK”按钮完成BMG IP核的配置,如下图所示:
图 7.5.13.5 “Summary”选项页 接下来会弹出询问是否在工程目录下创建存放IP核的文件,我们点击“OK”按钮即可。 紧接着会弹出“Genarate Output Products”窗口,我们直接点击“Generate”,如下图所示。
图 7.5.13.6 “Genarate Output Products”窗口 之后我们就可以在“Design Run”窗口的“Out-of-Context Module Runs”一栏中出现了该IP核对应的run“blk_mem_gen_0_synth_1”,其综合过程独立于顶层设计的综合,所以在我们可以看到其正在综合,如下图所示。
图 7.5.13.7 “blk_mem_gen_0_synth_1”run 在其Out-of-Context综合的过程中,我们就可以进行RTL编码了。首先打开IP核的例化模板,在“Source”窗口中的“IP Sources”选项卡中,依次用鼠标单击展开“IP”-“blk_mem_gen_0”-“Instantitation Template”,我们可以看到“blk_mem_gen_0.veo”文件,它是由IP核自动生成的只读的verilog例化模板文件,双击就可以打开它,如下图所示。
图 7.5.13.8 “blk_mem_gen_0.veo”文件 接下来我们创建一个新的设计文件,命名为ram_rw.v,代码如下:
1 module ram_rw(
2 input clk , //时钟信号
3 input rst_n , //复位信号,低电平有效
4
5 output ram_en , //ram使能信号
6 output ram_wea , //ram读写选择
7 output reg [4:0] ram_addr , //ram读写地址
8 output reg [7:0] ram_wr_data, //ram写数据
9 input [7:0] ram_rd_data //ram读数据
10 );
11
12 //reg define
13 reg [5:0] rw_cnt ; //读写控制计数器
14
15 //*****************************************************
16 //** main code
17 //*****************************************************
18
19 //控制RAM使能信号
20 assign ram_en = rst_n;
21 //rw_cnt计数范围在0~31,写入数据;32~63时,读出数据
22 assign ram_wea = (rw_cnt
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?