一、简介
RAM(Random Access Memory),即随机存取存储器。可以随时吧数据写入任一订定的地址的 存储单元,可以随时从任一指定地址独处数据。时钟频率决定读写速率。 RAM 重要用来存放程序以及程序执行过程中产生的中间数据和运算效果。
1、RAM分类
Altera FPGA 的 RAM IP 核分为两种类型:单端口 RAM 和双端口 RAM。
单端口 RAM:只有一组地址线控制着写数据端口和读数据端口。
双端口 RAM:具有两组地址线分别控制着写数据端口和读数据端口。
今天这篇文章我们来讲一下单端口RAM的相关使用。
2、 单端口的端口
二、单端口RAM的调用
1、单端口RAM选择
如图所示,在 IP Catalog 的搜刮栏中搜刮 RAM,然后选择 RAM:1-PORT。(这里和前面调用的pll一样也是需要先辈行工程创建,不清楚的小伙伴可以在前面的文章看看)
2、RAM存放位置的选择,这里和pll操作完全同等。
3、参数设置
如下图所示,该界面设置的参数有:
方框①:IP 核的输出数据位宽 方框
②:IP 核的存储容量 方框
③:储存单元类型,默认即可 方框
④:选择时钟模式,单时钟或双时钟。单时钟用一个时钟信号控制存储,这里选择单时 钟。然后点击 Next 进入下一界面。
4、输出端口寄存和时钟使能信号的选择
如图所示: 方框①:选择输出端口 q 是否寄存。
方框②:时钟使能信号,通常默认不勾选即可。
方框③:选择是否创建已补复位信号“aclr”和读使能信号“rden”。 点击“Next”进入下一界面。
5、同读同写时读数据的选择
如下图所示,该页面是设置某个地址写入数据同时读取数据的情况,是不关心,还是读出新 数据,或是读出旧数据。通常保持默认“New data”即可。
6、RAM存储器初始化参数设置
如图所示,本页面重要是设置 RAM 存储器初始化参数。:
方框①:是否设置初始化文件,根据需要选择,这里默认不初始即可。
方框②:选择是否允许系统存储器内容编辑器收罗和更新内容在与系统时钟无关的情况下, 默认不勾选即可。
7、仿真库文件的选择
如下图所示,表现的是仿真库文件 altera_mf。无需其它操作,点击“Next”进入下一界面。
8、天生文件的选择
如下图所示,该页面为需要设置天生的文件。勾选 ram_1port_inst.v 即可。ram_1port_bb.v 可勾可不勾选。然后点击 finish。
9、将文件添加到工程中
如下图所示,设置完成,点击“Yes”即可。
三、RAM的相关调用和仿真
1、设计文件的编写
在rtl文件夹中新建ip_ram.v文件,其中ram实例化代码可以从 ram_1port_inst.v 例化模板文件复制。如图:
- module ip_ram(
- input clk ,
- input rst_n ,
- input rden ,
- input wden ,
- input [8:0] address ,
- input [7:0] din ,
- output [7:0] dout
- );
-
-
- ram_1 ram_1_inst (
- .aclr ( ~rst_n ),
- .address ( address ),
- .clock ( clk ),
- .data ( din ),
- .rden ( rden ),
- .wren ( wden ),
- .q ( dout )
- );
-
- endmodule
复制代码 2、测试文件的编写
在tb文件夹中新建tb_ram。v文件。如图:
- `timescale 1ns/1ns
-
- module tb_ram();
- //激励信号定义
- reg clk ;
- reg rst_n ;
- reg rden ;
- reg wden ;
- reg [8:0] address ;
- reg [7:0] din ;
- //输出信号定义
- wire [7:0] dout ;
- //时钟周期参数定义
- parameter CLOCK_CYCLE = 20;
- //模块例化
- ip_ram ip_ram_inst(
- /*input */.clk (clk ),
- /*input */.rst_n (rst_n),
- /*input */.rden (rden ),
- /*input */.wden (wden ),
- /*input [8:0] */.address (address),
- /*input [7:0] */.din (din ),
- /*output [7:0] */.dout (dout )
- );
- //产生时钟
- initial clk = 1'b0;
- always #(CLOCK_CYCLE/2) clk = ~clk;
- //产生激励
- integer i;
- initial begin
-
- rst_n = 1'b0;
- wden = 1'b0;
- rden = 1'b0;
- din = 9'h00;
- #(CLOCK_CYCLE*20);
- rst_n = 1'b1;
- #10;
- //写入600个数据
- for (i = 0;i<600;i=i+1) begin
- wden = 1'b1;
- address = i;
- din = 8'($random);
- @(posedge clk);
- wden=1'b0;
- rden = 1'b1;
- address = i;
- @(posedge clk);
- rden =1'b0;
- end
- //复位,验证ram写入的数据是否清空
- #CLOCK_CYCLE;
- rst_n = 1'b0;
- #(CLOCK_CYCLE*20);
- rst_n = 1'b1;
- #10;
- //重新从地址0写入20个数据
- for (i = 0;i<20;i=i+1) begin
- wden = 1'b1;
- address = i;
- din = 8'($random);
- @(posedge clk);
- wden=1'b0;
- end
- #(CLOCK_CYCLE*20);
- #5;
- i=0;
- //从地址0开始,读20个数据
- repeat(20)begin
- rden = 1'b1;
- address = i;
- i = i + 1;
- @(posedge clk);
- end
- rden = 0;
- #(CLOCK_CYCLE*100);
- $stop;
- end
- endmodule
复制代码 3、波形仿真
通过对比波形图中的写入和读出数据等的相关比较。我们可以看到RAM可以或许成功的举行调用,到这里单端口的RAM调用结束。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |