fpga 单口ram读写操作(block memroy generator)
单口RAM读写测试
硬件资源
IP核:block memory generator
IP核主要设置
-
Interface Type:Native
-
Memory Type:单口ram,双端口ram,真双端口ram
-
Memory Size:按照项目进行设置
-
对于Primitives output registor 如果勾选会导致时钟落后两个个周期,否则若后一个周期,详见这篇文章
单端口ram接口介绍
- addra: 读写地址
- clka:读写时钟
- dina:写入数据
- douta:读出数据
- ena:总使能
- wea:读写使能(1读使能,0写使能)
模块介绍
- 测试模块:sim_rw_ram
- 用于激发时钟与rst_n
- v_rw_ram
- 用于实例ram_gen与blk_mem_gen_0两个模块
- ram_gen
- 内部激发din,dout,addr
- blk_mem_gen_0
- IP核
测试模块(sim_rw_ram)
`timescale 1ns / 1ps
module sim_rw_ram();
reg clk,rst_n;
initial begin
clk <= 1;
rst_n <= 0;
#5 rst_n <= 1;
end
always#5 clk <= ~clk;
v_rw_ram v1(
.clk(clk),
.rst_n(rst_n));
endmodule
v_rw_ram
`timescale 1ns / 1ps
module v_rw_ram(input clk,
input rst_n);
wire[31:0] dout,din;
wire en,we;
wire [4:0]addr;
ram_gen v_ram_gen(
.clk(clk),
.rst_n(rst_n),
.dout(dout),
.en(en),
.we(we),
.addr(addr),
.din(din)
);
blk_mem_gen_0 ip_ram (
.clka(clk), // input wire clka
.ena(en), // input wire ena
.wea(we), // input wire [0 : 0] wea
.addra(addr), // input wire [4 : 0] addra
.dina(din), // input wire [31 : 0] dina
.douta(dout) // output wire [31 : 0] douta
);
endmodule
ram_gen
`timescale 1ns / 1ps
module ram_gen(input clk,
input rst_n,
input [31:0]dout,
output en,
output we,
output reg [4:0]addr,
output reg [31:0]din);
assign en = rst_n;
reg [4:0]cnt;
assign we = (en == 1&&cnt< 16)?1'b1:1'b0;
always @(posedge clk or negedge rst_n) begin
if (~rst_n)begin
cnt <= 0;
end
else if (cnt<31) begin
cnt <= cnt+1;
end
else begin
cnt <= 0;
end
end
always @(posedge clk or negedge rst_n) begin
if (~rst_n)begin
din <= 0;
end
else if (cnt<16)begin
din <= din+1;
end
else begin
din <= 0;
end
end
always @(posedge clk or negedge rst_n) begin
if (~rst_n)begin
addr <= 0;
end
else if (cnt<31) begin
addr <= cnt==15?0:addr+1;
end
else begin
addr <= 0;
end
end
endmodule
波形显示
- 整体波形