笔记四是简单介绍RAM IP核的使用,RAM是随机存储器,它是可读可写的存储器,可以先将数据写进去,然后在按照顺序读取。
1.打开VIVADO ,点击IP Catalog
2.搜素RAM,选择Block Memory Genertor
3. 配置参数
(1) 选择Single Port RAM
(2) 选择读写位宽和深度,据具体情况而定;Operating Mode选择No Change
(3) 因为是RAM,因此不用加载coe文件
4.读写文件
RAM的输入是时钟clk,复位rst_n,使能信号,读写切换信号,地址,输出是写的数据。
在使能信号为高电平以及读写切换信号为高电平的时候,进行写数据;当读写切换信号为低电平的时候按照地址读数据。
module ram_rw(
input clk, // 输入clk
input rst_n, // 输入复位
output reg ram_en, // 输入RAM使能信号
output reg rw, // 读写切换信号
output reg [4:0] ram_addr, // RAM的地址
output reg [7:0] ram_wr_data // RAM数据变量
);
// 复位为0时,使能信号为0;复位为1时,使能信号为1
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
ram_en <= 1'b0;
else
ram_en <= 1'b1;
end
//定义读写控制的计数器 在计数器在0~31之间用来写数据,在32~63之间用来读数据
reg [5:0] rw_cnt;
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
rw_cnt <= 6'd0;
else if(rw_cnt == 6'd63)
rw_cnt <= 6'd0;
else
rw_cnt <= rw_cnt + 6'b1;
end
//写数据
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
ram_wr_data <= 0;
else if((rw_cnt <= 6'd31) && ram_en)
ram_wr_data <= ram_wr_data + 8'd1;
else
ram_wr_data <= ram_wr_data;
end
//读写控制
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
rw <= 1'b1;
else if((rw_cnt <= 6'd31) && ram_en)
rw <= 1'b1;
else
rw <= 1'b0;
end
//地址为计数器的低五位数据
always@(posedge clk or negedge rst_n)
begin
if(~rst_n)
ram_addr <= 5'd0;
else
ram_addr <= rw_cnt[4:0];//低五位数据,0~31
end
endmodule
5.顶层文件
module top_ram(
input clk, // 输入clk
input rst_n, // 输入复位
output [7:0] dout // 8bit输出
);
wire ram_en,rw; // 使能和读写切换
wire [4:0] ram_addr; // 地址
wire [7:0] ram_wr_data; // 数据
//例化
ram_rw u1 (
.clk(clk),
.rst_n(rst_n),
.ram_en(ram_en),
.rw(rw),
.ram_addr(ram_addr),
.ram_wr_data(ram_wr_data)
);
//例化
blk_mem_gen_0 u2 (
.clka(clk), // input wire clka
.ena(ram_en), // input wire ena
.wea(rw), // input wire [0 : 0] wea
.addra(ram_addr), // input wire [4 : 0] addra
.dina(ram_wr_data), // input wire [7 : 0] dina
.douta(dout) // output wire [7 : 0] douta
);
endmodule
6.测试文件
module tb_ram;
reg clk,rst_n; // 输入clk,复位
wire [7:0] dout; // 输出8bit数据
// 例化
top_ram U3(
.clk(clk),
.rst_n(rst_n),
.dout(dout)
);
// 初始化
initial
begin
clk = 1'b0; // 初始clk为0
rst_n = 1'b0; // 初始复位为0
#50 // 延时50ns
rst_n = 1'b1; // 复位为1
end
always #10 clk = ~clk; // clk周期为20ns
endmodule
7.结果展示
点击U3,选中ram_add和ram_cnt,右键Add 通Wave Window,然后点击刷新就可以把它们加进仿真窗口显示
选中需要更改的信号,右键,点击Radix,选择Unsigned Decimal(无符号十进制数)