Vivado中BRAM IP的配置方式和使用技巧

描述

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

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

一、BRAM IP核的配置

1、打开BRAM IP核

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

IP核

2、配置BRAM IP基本参数

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端口的参数配置。

IP核

(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来说很重要。

IP核

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

5、IP设置参数总览

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

IP核

6、点击OK生成IP核。

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

IP核

二、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

仿真测试图:

IP核

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分