本文转载自:VagueCheung的博客
Vivado2017.2 中BRAM版本为 Block Memory Generator Specific Features 8.3
BRAM IP核包括有5种类型:
Single-port RAM 单端口RAM
Simple Dual-port RAM 简单双端口RAM(A写数据B读数据)
True Dual-port RAM 双端口RAM
Single-por ROM 单端口ROM
Dual-port ROM 双端口ROM
BRAM核支持两种总线形式的输入输出:Native or AXI4
以下图配置为例:Single-port RAM
Testbench 测试代码如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2018/11/21 15:52:48
// Design Name:
// Module Name: test_bench_BRAM
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test_bench_BRAM(
);
reg[15:0] mem1_re[0:15]; //输入数据存储器
integer i;
// blk_mem_gen_0 inputs
reg clka;
reg ena;
reg wea;
reg[3:0] addra;
reg[15:0] dina;
// blk_mem_gen_0 outputs
wire[15:0] douta;
blk_mem_gen_0 blk_mem_gen_m0
(
.clka(clka), //BRAM 输入时钟信号
.ena(ena), //BRAM 时钟使能信号
.wea(wea), //写使能信号
.addra(addra), //地址信号
.dina(dina), //数据输入接口 写入
.douta(douta) //数据输出接口 读出
);
always #5 clka = ~clka;
initial $readmemh("D:/fpga/fft1/stimulus1_24bit.dat",mem1_re); //数据是[1 2 3 4 5 6 7 8 9]
initial begin
clka = 0;
ena = 0;
wea = 0;
addra = 0;
dina = 0;
#150 ena = 1;
begin
for(i=0;i<16;i=i+1) begin
#10 wea <= 1;
addra <= i;
/*if(i == 0) begin
addra <= 0;
end
else if (i == 1) begin
addra <= 1;
end
else if(i == 2) begin
addra <= 2;
end
else if(i == 3) begin
addra <= 3;
end
else begin
wea <= 0;
end*/
dina <= {mem1_re[i]};
if(i == 15) begin
dina <= 0;
wea <= 0;
end
$display("mem_a[%d] = %h", i, mem1_re[i]);
end
end
#40000 $finish;
end
endmodule
仿真结果如下:
配置为simple dual port ram
Testbench
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2018/11/21 15:52:48
// Design Name:
// Module Name: test_bench_BRAM
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test_bench_BRAM(
);
reg[15:0] mem1_re[0:15]; //输入数据存储器
integer i;
integer j;
// blk_mem_gen_0 inputs
reg clk;
reg ena;
reg enb;
reg wea;
reg[3:0] addra;
reg[3:0] addrb;
reg[15:0] dina;
// blk_mem_gen_0 outputs
wire[15:0] douta;
wire[15:0] doutb;
/*****单端口 网络配置的IP核
blk_mem_gen_0 blk_mem_gen_m0
(
.clka(clka), //BRAM 输入时钟信号
.ena(ena), //BRAM 时钟使能信号
.wea(wea), //写使能信号
.addra(addra), //地址信号
.dina(dina), //数据输入接口 写入
.douta(douta)
);*******/
/**************简单双端口RAM A进B出**************/
blk_mem_gen_0 blk_mem_gen_m0
(
.clka(clk), //BRAM 输入时钟信号
.ena(ena), //BRAM 时钟使能信号
.wea(wea), //写使能信号
.addra(addra), //地址信号
.dina(dina), //数据输入接口 写入
.clkb(clk), //BRAM 输入时钟信号
.enb(enb), //BRAM 时钟使能信号
.addrb(addrb), //地址信号
.doutb(doutb)
);
always #5 clk = ~clk;
initial $readmemh("D:/fpga/fft1/stimulus1_24bit.dat",mem1_re);
initial begin
clk = 0;
ena = 0;
enb = 0;
wea = 0;
addra = 0;
addrb = 0;
dina = 0;
#150 ena = 1;
begin
for(i=0;i<16;i=i+1) begin
#10 wea <= 1;
addra <= i;
dina <= {mem1_re[i]};
if(i == 15) begin
dina <= 0;
wea <= 0;
addra <= 0;
end
$display("mem_a[%d] = %h", i, mem1_re[i]);
end
for(j=0;j<16;j=j+1) begin
#10 addrb <= j;
enb <= 1;
if( j == 15) begin
enb <= 0;
addrb <= 0;
end
end
end
#40000 $finish;
end
endmodule
测试仿真结果: