创建工程后,在IP Catalog中输入:“BLOCK Memory Generator”,注意选择下面的IP核。
成功创建IP核后,在IP Sources中找到.veo文件,复制例化模板
到.v文件中,
blk_mem_gen_0 your_instance_name (
.clka(clka), // input wire clka 时钟
.rsta(rsta), // input wire rsta 复位
.ena(ena), // input wire ena 使能
.wea(wea), // input wire [0 : 0] wea 读写判断
.addra(addra), // input wire [4 : 0] addra 地址线
.dina(dina), // input wire [7 : 0] dina 写数据
.douta(douta), // output wire [7 : 0] douta 读数据
.rsta_busy(rsta_busy) // output wire rsta_busy
);
ip_ram.v
`timescale 1ns / 1ps
module ip_ram(
input sys_clk,
input sys_rst_n
);
wire ram_en;
wire ram_wea;
wire [4:0] ram_addr;
wire [7:0] ram_wr_data;
wire [7:0] ram_rd_data; //由于接口要接入顶层模块和IP核中,因此定义wire型
ram_rw raw_rw_u(
.clk (sys_clk),
.rst (sys_rst_n),
.ram_en (ram_en),
.ram_wea (ram_wea),
.ram_addr (ram_addr),
.ram_wr_data (ram_wr_data),
.ram_rd_data (ram_rd_data)
);
blk_mem_gen_0 blk_mem_gen_0_u (
.clka(sys_clk), // input wire clka
.rsta(!sys_rst_n), // input wire rsta
.ena(ram_en), // input wire ena
.wea(ram_wea), // input wire [0 : 0] wea
.addra(ram_addr), // input wire [4 : 0] addra
.dina(ram_wr_data), // input wire [7 : 0] dina
.douta(ram_rd_data), // output wire [7 : 0] douta
.rsta_busy() // 用于指示ram是否处于工作忙状态,该处不用
);
endmodule
ram_rw.v
`timescale 1ns / 1ps
module ram_rw(
input clk,
input rst,
output ram_en,
output ram_wea,
output reg[4:0] ram_addr,
output reg[7:0] ram_wr_data,
input [7:0] ram_rd_data //使用ILA调试查看读端口,正常使用无需定义该端口
);
reg [5:0] rw_cnt; //读写计数器 0-63,
assign ram_wea=(rw_cnt<=31&&ram_en)?1'b1:1'b0; //三模运算,计数器小于等于31且使能打开,用于控制计数器1的读写切换
assign ram_en=rst; //由于复位常高,因此赋给使能,能在按下复位时使能一起被关断
//计数器1,控制读写
always@(posedge clk or negedge rst) begin
if(!rst)
rw_cnt<=1'b0;
else if(rw_cnt==6'd63)
rw_cnt<=1'b0;
else
rw_cnt<=rw_cnt+1'b1;
end
//计数器2,控制写入数据
always@(posedge clk or negedge rst) begin
if(!rst)
ram_wr_data<=0;
else if(ram_wr_data<=6'd31) //小于等于31时,计数器加1
ram_wr_data<=ram_wr_data+1'b1;
else
ram_wr_data<=0;
end
//计数器3,控制地址线
always@(posedge clk or negedge rst) begin
if(!rst)
ram_addr<=0;
else if(ram_addr==6'd31)
ram_addr<=0;
else
ram_addr<=ram_addr+1'b1;
end
ila_0 ila_0_u (
.clk(clk), // input wire clk
.probe0(ram_en), // input wire [0:0] probe0
.probe1(ram_wea), // input wire [0:0] probe1
.probe2(ram_addr), // input wire [4:0] probe2
.probe3(ram_wr_data), // input wire [7:0] probe3
.probe4(ram_rd_data) // input wire [7:0] probe4
);
endmodule
ram.xdc
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U2 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]
链接: 正点原子 RAM IP核