[FPGA IP系列] BRAM IP参数配置与使用示例

本文转载自:FPGA入门到精通微信公众号

FPGA开发中使用频率非常高的两个IP就是FIFO和BRAM,上一篇文章中已经详细介绍了Vivado FIFO IP,今天我们来聊一聊BRAM IP。

本文将详细介绍Vivado中BRAM IP的配置方式和使用技巧。

一、BRAM IP核的配置

1、打开BRAM IP核

在Vivado的IP Catalog中找到Block Memory Generator IP核,双击打开参数配置界面。

2、配置BRAM IP基本参数

(1)IP名

定制的IP的名字只能在定制时设定好,后续不能修改。

IP名设定,简单易懂即可,按照功能或数据宽度和深度来设定即可,例如BRAM_8x256,即表示数据宽度为8bit,数据深度为256bit。

(2)接口类型(Interface Type)

Native:最基本的接口,包括数据写入、数据读取等信号。

AXI4:AXI4总线通信协议接口

(3)存储类型(Memory Type)

Single Port RAM:单端口RAM

Simple Dual Port RAM:简单双端口RAM,可选同步时钟和异步时钟,A端口只支持写数据,B端口只支持读数据。

True Dual Port RAM:真双端口RAM,可选同步时钟和异步时钟,A端口和B端口都支持写数据和读数据。

Single Port ROM:单端口ROM

Dual Port ROM:双端口ROM,A端口和B端口都可以读取数据

3、配置A端口或B端口参数

A端口和B端口参数配置界面基本一致,这里只介绍A端口的参数配置。

(1)存储大小设置(Memory Size)

设置读数据或写数据端的数据位宽和深度,数据位宽范围为1~4608bit,数存储深度为2~1048576。

operating mode:读写同一个地址时,操作模式设定:写优先、读优先、不变,建议在实际应用时不出现这种情况。

Enable Port Type:设定是否开放端口使能控制信号。

(2)输出数据寄存设置

Primitives Output Register:输出数据是否插入一个寄存器,如果不选中这个,则读数据延时只有1个周期,否则读数据延时有2个周期。

建议选中这个输出寄存器,可以改善时序。

(3)复位参数设置

RSTA Pin (setreset pin):复位端口选择,如果选中,则开放复位端口。

Output Reset Value (Hex):设定复位生效后,输出数据值,默认为0

4、Other Options

这部分初始化值,对于RAM来说可能用处不大,但对于ROM来说很重要。

选中这个Load Init File,再点击“Browse”选中“coe或mif”格式文件,最后点击“Edit”,在打开的界面选择“Valide”校验一下,如果有问题,这部分会提示红色文字,否则继续下一步即可。

5、IP设置参数总览

IP设置参数总览,可看到资源消耗、宽度、深度、读延迟等信息。

6、点击OK生成IP核。

在IP核生成完成后,点击source窗口下的“IP source”,鼠标左键单击这个IP,在“Instantiation Template”下,双击“veo”后缀文件,即可看到例化模板。

二、BRAM IP核的接口

1、时钟信号和复位信号

复位信号 rsta/rstb

时钟 clka(A端口时钟) clkb(b端口时钟),复位信号 rsta(A端口复位),rstb(B端口复位)

2、端口信号

A和B端口信号基本一样,这里以A端口为例。

ena A端口使能信号

wea A端口写使能信号

addra A端口读写地址

dina A端口的写入数据

douta A端口的读取数据

三、BRAM IP核的调用

BRAM IP核的调用很简单,这里以同步时钟下的简单双端口RAM为例:

module top (
input clk,
input [7:0] data_in,
input wr_en,
input [7:0] wr_addr,
input [7:0] rd_addr,
output [7:0] data_out
);

BRAM_8x256 u_BRAM_8x256 (
.clka(clk), // input wire clka
.ena(1'b1), // input wire ena
.wea(wr_en), // input wire [0 : 0] wea
.addra(wr_addr), // input wire [7 : 0] addra
.dina(data_in), // input wire [7 : 0] dina
.clkb(clk), // input wire clkb
.enb(1'b1), // input wire enb
.addrb(rd_addr), // input wire [7 : 0] addrb
.doutb(data_out) // output wire [7 : 0] doutb
);

endmodule

下面是BRAM IP核的一个简单的testbench:

module test;

reg clk;
reg [7:0] din;
reg wen;
reg [7:0] waddr;
reg [7:0] raddr;
wire [7:0] dout;

top u_top(
.clk(clk),
.data_in(din),
.wr_en(wen),
.wr_addr(waddr),
.rd_addr(raddr),
.data_out(dout)
);

initial begin
clk = 0;
wen = 0; waddr = 0; raddr = 0;
#10 wen = 1; waddr = 1; din = 5;
#10 wen = 1; waddr = 2; din = 6;
#10 wen = 1; waddr = 3; din = 7;
#10 wen = 1; waddr = 4; din = 8;
#10 wen = 1; waddr = 5; din = 9;
#10 wen = 0; raddr = 1;
#10 wen = 0; raddr = 2;
#10 wen = 0; raddr = 3;
#10 wen = 0; raddr = 4;
#10 wen = 0; raddr = 5;
#30 $finish;
end

always #5 clk = ~clk;

endmodule

仿真测试图:

参考文献:

https://docs.xilinx.com/v/u/en-US/pg058-blk-mem-gen

https://pan.quark.cn/s/df67709144f5

最新文章

最新文章