作者:贺磊
一、 简单介绍
所谓rom就是只读存储器,也就是说,我们不能对其内部写入数据,属于一个内部存储器,但存储数据有限。
二、 操作步骤
1. 创建一个rom的初始化文件———mif文件(用来存储初始化数据),立刻另存为num.mif,如图1所示。
图1
2. 定义位宽和深度(在此次设计中,选择位宽为8,深度为256),如图2所示。
图2
3. 填充数据(选择从0-255递增的填充方式),如图3,图4所示。
图3
图4
4. Mif文件创建成功,数据从0开始,每次递增1,如图5,6,7所示。
图5
图6
图7
5. 在ip核中创建rom,选择rom:1-port,如图8,9。
图8
图9
6. 选择语言类型为verilog,同时为ip核命名,如图10。
图10
7. 进入到rom的设置向导,设置深度和位宽(与mif文件保持一致),如图11。
图11
8. 去掉端口的寄存器(如果不去掉的话,就会使输出延迟一拍),如图12。
图12
9. 把我们之前生成的mif文件添加进去,如图13。
如图13
10. 完成rom的设置,如图14。
图14
三、 设计需求
设计一个rom控制器,该控制器负责输出0-255递增的地址数据,将地址总线连接到rom地址输入端,看输出的数据是否正确。
四、 顶层架构设计
说明:由于是rom是只读存储器,需要我们指定地址,它才能输出地址对应的数据。
五、 建模与验证
/*Author : 贺磊
Data :2017/2/19
Mode : rom_control
*/
00module rom_control(clk, rst_n, addr);
01
02input clk;//系统时钟50m
03input rst_n;//复位低电平有效
04output reg [7:0] addr;
05
06always @ (posedge clk or negedge rst_n)
07begin
08if(!rst_n)
09addr <= 0;
10else if(addr < 255)
11addr <= addr + 1;
12else
13addr <= 0;
14end
15
16endmodule
17
/*Author : 贺磊
Data :2017/2/19
Mode : rom
*/
00module rom(clk, rst_n, q);
01
02input clk;//系统时钟50m
03input rst_n;//低电平复位有效
04output [7:0] q; //rom输出数据
05
06wire [7:0] addr;//中间地址寄存器
07
08rom_control rom_con(
09.clk(clk),
10.rst_n(rst_n),
11.addr(addr)
12);
13
14my_rom my_rom(
15.address(addr),
16.clock(clk),
17.q(q)
18);
19
20endmodule
21
RTL级视图如下:
Testbench的验证:
/*Author : 贺磊
Data :2017/2/19
Mode : rom_tb
*/
00`timescale 1ns/1ps
01module rom_tb;
02
03reg clk;
04reg rst_n;
05wire [7:0] q;
06
07rom rom_dut(
08.clk(clk),
09.rst_n(rst_n),
10.q(q)
11);
12
13initial
14begin
15clk = 1;
16rst_n = 0;
17#200.1
18rst_n = 1;
19end
20
21initial
22#6000 $stop;
23
24always #10 clk = ~clk;
25
26endmodule
27
仿真结果如下:
说明:从仿真我们可以清楚的看到,当地址开始变化的时候(从0-255),数据也在随着地址的变化而变化,也就是说地址递增一位,数据也会在下一拍递增一位。而这下一拍是由rom内部结构决定的,从而验证我们设计正确。
——END——
注:至芯科技已开设FPGA初级直播课,有需要的小伙伴可以分享这篇文章并截图。发送到以下微信,即可获取直播链接。并有机会加入直播授课群,和志同道合的朋友一起探讨、学习!
欢迎关注FPGA设计论坛,实时获取更多FPGA相关资讯