优化FPGA设计中BRAM资源的使用

FPGA设计中BRAM(Block RAMs)资源的使用

  RAM分为BRAM(Block RAMs)和DRAM(Distributed RAM),即块RAM与分布式RAM,这两个差别在于BRAM是FPGA上固有的一些存储资源(针对不同型号的FPGA,其存储资源大小会有差别),而DRAM则是由LUT组合而成的。所以在数据量较大的情况下,一般使用BRAM,尽量避免使用DRAM,导致LUT资源的浪费。
  以Vivado平台为例,如果不指定综合为BRAM还是DRAM,则Vivado会根据RAM的大小自动判断综合为BRAM还是DRAM。
  参考博客《单端口RAM设计》中的单端口RAM代码,如下。

`timescale 1ns / 1ps

module single_port_ram (
clk         , // Clock Input
address     , // Address Input
data        , // Data bi-directional
cs          , // Chip Select
we          , // Write Enable/Read Enable
oe            // Output Enable
); 
 
parameter DATA_WIDTH = 8 ;
parameter ADDR_WIDTH = 4 ;
parameter RAM_DEPTH = 1 << ADDR_WIDTH;
 
//--------------Input Ports----------------------- 
input                  clk         ;
input [ADDR_WIDTH-1:0] address     ;
input                  cs          ;
input                  we          ;
input                  oe          ; 
 
//--------------Inout Ports----------------------- 
inout [DATA_WIDTH-1:0]  data       ;
 
//--------------Internal variables---------------- 
reg [DATA_WIDTH-1:0] data_out ;
//(*ram_style = "block"*) reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
reg                  oe_r;
 
 
//initialization
 
// synopsys_translate_off
integer i;
initial begin
    //$readmemb("F:/IP_core/Single Port RAM/SIM/single_port_rom_init.txt", mem);
	for(i=0; i < RAM_DEPTH; i = i + 1) begin
        mem[i] = 8'h00;
    end
end
// synopsys_translate_on
 

 
//--------------Code Starts Here------------------ 
 
// Tri-State Buffer control 
// output : When we = 0, oe = 1, cs = 1
assign data = (cs && oe && !we) ? data_out : 8'bz; 
 
// Memory Write Block 
// Write Operation : When we = 1, cs = 1
always @ (posedge clk)
begin : MEM_WRITE
   if ( cs && we ) begin
       mem[address] <= data;
   end
end
 
// Memory Read Block 
// Read Operation : When we = 0, oe = 1, cs = 1
always @ (posedge clk)
begin : MEM_READ
  if (cs && !we && oe) begin
    data_out <= mem[address];
/*     oe_r <= 1;
  end else begin
    oe_r <= 0; */
  end
end
 
endmodule // End of Module ram_sp_sr_sw

  对该代码进行综合,可以看到资源使用报告如下。可以看到这里根据RAM的大小自动综合成DRAM(LUTRAM)。


  于是,参考Xilinx Template给出模板(或者在Xilinx官方文档UG901中也可查看),指定将RAM综合为BRAM,如下图所示。

  在寄存器前面加上语句: (*ram_style=“block”*),即

	reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; //修改前
	(*ram_style = "block"*) reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; //修改后

  再进行综合,查看资源使用报告,可见此时我们编写的单端口RAM已经被综合成了BRAM。

注意:这里由于所设计的RAM不大,所以在不指定RAM的类型时会自动综合成了DRAM,但是在RAM的存储空间较大时,会自动综合成BRAM,可以通过在前面加入语句 (*ram_style=“distributed”*)指定综合为DRAM。

参考资料
1、FPGA单端口RAM的设计(同步读、同步写)
2、UG901(Xilinx官方设计文档)

物联沃分享整理
物联沃-IOTWORD物联网 » 优化FPGA设计中BRAM资源的使用

发表评论