当前位置:   article > 正文

ZYNQ之FPGA 片内ROM读写测试实验_zynq rom

zynq rom


前言

FPGA本身是SRAM架构的,断电之后程序就会消失,那么如何利用FPGA实现一个ROM呢,我们可以利用FPGA内部的RAM资源实现ROM,但这不是真正意义上的ROM,而是每次上电都会把初始化的值先写入RAM。Vivado软件中提供了ROM的IP核 , 我们只需通过IP核例化一个ROM,根据ROM的读时序来读取ROM中存储的数据。本实验将介绍如何使用FPGA内部的ROM以及程序对该ROM的数据读操作。该实验与ZYNQ之FPGA 片内RAM读写测试实验操作类似,可以参考。


一、创建ROM初始化文件

对于ROM,我们需要提前准备好数据,这样在FPGA 实际运行时,就可以直接读取这些ROM中预存好的数据了。Xilinx FPGA 的片内ROM支持初始化数据配置,我们可以创建一个后缀名为“.coe”的ROM初始化文件。
首先创建一个名为rom_test的文件夹。
在这里插入图片描述
然后在该文件夹下新建一个文本文档,将其后缀名改为“.coe”,我这里给文件命名为rom_init.coe。
在这里插入图片描述rom_init.coe文件中的内容如下。

//该代码来自正点原子
MEMORY_INITIALIZATION_RADIX=16;        //表示ROM内容的数据格式是16进制
MEMORY_INITIALIZATION_VECTOR= 
11,
22,
33,
44,
55,
66,
77,
88,
99,
aa,
bb,
cc,
dd,
ee,
ff,
00,
a1,
a2,
a3,
a4,
a5,
a6,
a7,
a8,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8;       //每个数据后面用逗号或者空格或者换行符隔开,最后一个数据后面加分号
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

ROM初始化文件的内容格式比较简单,其中,第1行为定义的数据格式,第3行到第34行是这个 32*8bit 大小ROM的初始化数据,每行数字后面用逗号,最后一行数字结束时用分号。


二、添加ROM IP核

先新建一个名为rom_test的Vivado工程,具体的步骤可以参见:Vivado软件的使用——以led的交替闪烁为例
新工程到下图所示的界面后点击Finish即可完成工程的创建。
在这里插入图片描述
接着在工程中添加ROM IP,步骤为依次按照下图中的序号找到Block Memory Generator双击打开。
在这里插入图片描述
在弹出的对话框中的Basic下修改Component Name为rom_ip,修改Memory Type为Single Port ROM。
在这里插入图片描述
在Port A Options下按照下图中的序号依次修改。
在这里插入图片描述
把Primitives Output Register取消勾选,其功能是在输出数据上加寄存器,这可以有效改善时序 ,但读出的数据会落后地址两个周期,因此在很多情况下,不用这项功能,保持读出的数据落后地址一个周期即可。
在Other Options下勾选Load Init File,然后点击Browse查找第一步中创建好的文件rom_init.coe。
在这里插入图片描述
按照下图中序号依次选择到ROM的初始化文件。
在这里插入图片描述
可以看到该文件已经添加成功了,点击OK即可。
在这里插入图片描述
在弹出的对话框中点击Generate就可以生成ROM IP。
在这里插入图片描述


三、编写测试程序

ROM的程序设计非常简单,在程序中我们只要每个时钟改变ROM的地址,ROM就会输出当前地址的内部存储数据 ,例化ILA,用于观察地址和数据的变化。
新建名为rom_test的Verilog文件,依次按照下图中标注的序号进行即可。
在这里插入图片描述
在新建好的rom_test.v中写入如下代码。

//该代码来自正点原子
`timescale 1ns / 1ps

module rom_test(
	input sys_clk,	//50MHz时钟
	input rst_n		//复位,低电平有效
    );

wire [7:0] rom_data;	  //ROM读出数据
reg	 [4:0] rom_addr;      //ROM输入地址 

//产生ROM地址读取数据
always @ (posedge sys_clk or negedge rst_n)
begin
    if(!rst_n)
        rom_addr <= 10'd0;
    else
        rom_addr <= rom_addr+1'b1;
end        
//实例化ROM
rom_ip rom_ip_inst
(
    .clka   (sys_clk),      //inoput clka
    .addra  (rom_addr),      //input [4:0] addra
    .douta  (rom_data)       //output [7:0] douta
);
//实例化逻辑分析仪
ila_0 ila_m0
(
    .clk    (sys_clk),
    .probe0 (rom_addr),
	.probe1 (rom_data)
);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

其中实例化ROM部分的代码来自rom_ip中的rom_ip.veo文件,不过需要将括号内的参数做一修改。
在这里插入图片描述


四、添加ILA

我们还需要添加ILA,其添加过程可参见:使用Vivado软件进行硬件调试
探针的数量这里设置为2,即rom_addr和rom_data两个探针。
在这里插入图片描述
这里每个探针的位数按照代码中的分配,rom_addr是5位,rom_data是8位。
在这里插入图片描述
对应的代码如下。

wire [7:0] rom_data;	  //ROM读出数据
reg	 [4:0] rom_addr;      //ROM输入地址 
  • 1
  • 2

在弹出的对话框中点击Generate即可。
在这里插入图片描述
实例化ILA逻辑分析仪部分的代码来自ila_0中的ila_0.veo文件,不过需要将括号内的参数做一修改。
在这里插入图片描述


五、分配管脚

本实验中需要分配管脚的只有时钟信号clk(管脚为U18)和复位信号rst_n(管脚为N15),按照下图中的数字顺序即可完成管脚的分配。
在这里插入图片描述
管脚分配完成后Ctrl+S保存,名称与工程名保持一致。
在这里插入图片描述
管脚分配的信息在rom_test.xdc文件中。
在这里插入图片描述


六、Simulator仿真

Simulator仿真创建文件的过程可参见:Vivado中Simulator仿真软件的使用
右击Simulation Sources选择Add Source按照下图中序号依次新建TB文件。
在这里插入图片描述
在tb_rom_test.v文件中写入如下代码。

//该代码来自正点原子
`timescale 1ns / 1ps

module vtf_rom_tb;
// Inputs
reg sys_clk;
reg rst_n;

// Instantiate the Unit Under Test (UUT)
rom_test uut (
	.sys_clk	(sys_clk), 		
	.rst_n		(rst_n)
);

initial 
begin
	// Initialize Inputs
	sys_clk = 0;
	rst_n = 0;

	// Wait 100 ns for global reset to finish
	#100;
      rst_n = 1;       

 end

always #10 sys_clk = ~ sys_clk;   //20ns一个周期,产生50MHz时钟源
   
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

保存代码后选择SIMULATION下的Run Simulation,选择第一个行为仿真。
将所有代码中定义的信号拖入到波形仿真窗口,设置仿真时间为1000ns,运行后结果如下图所示。
在这里插入图片描述
由上图可知,该仿真结果与RAM读取数据一样,数据滞后于地址一个周期。


七、硬件调试

连接开发板,点击Generate Bitstream生成比特流文件,并将其下载到开发板上。
在这里插入图片描述
下载后弹出如下窗口,设置rom_addr的初始数值为00,然后点击运行按钮,得到如下波形,将游标移动到红线所在位置并放大得到下图。
在这里插入图片描述
由上图可以知道,硬件调试的结果与仿真的结果一致。


总结

以上就是ZYNQ之FPGA 片内ROM读写测试实验的所有内容了,该实验过程与ZYNQ之FPGA 片内RAM读写测试实验非常相似,大的不同就是该实验需要创建ROM初始化文件,然后在添加ROM IP核时选上该文件。
本文参考资料:正点原子–course_s1_ZYNQ那些事儿-FPGA实验篇V1.06.pdf

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号