在FPGA设计中经常要使用片内RAM资源来缓存数据。对于Xilinx FPGA器件,片内存储资源分为块存储Block RAM和分布式存储Distributed RAM。Block RAM为硬核,不会占用触发器FF和查找表LUT这类逻辑资源。而Distributed RAM是通过LUT和FF搭建而成,会占用逻辑资源。因此,在进行程序设计时会优先考虑使用Block RAM资源。
一般情况下,要使用Xilinx FPGA内的RAM资源,可通过vivado软件IP Catalog中的Block Memory Generator和Distributed Memory Generator配置参数例化生成1个RAM的IP核。
对于一些复杂的设计,需要使用很多位宽不同,深度不同的RAM时,通过例化IP核的方式便会带来一些问题:
因此,本文介绍通过verilog描述RAM的方法,使其综合、布局布线后的结果与使用IP核例化RAM的效果相同。
本文内容参考自AMD Xilinx官方文档UG901。
module bram_sp #
(
parameter DATA_WIDTH = 8,
parameter ADDR_WIDTH = 11,
parameter OP_MODE = "NO_CHANGE" //WRITE_FIRST, READ_FIRST or NO_CHANGE
)
(
input wire clk,
input wire we,
input wire en,
input wire [ADDR_WIDTH - 1:0] addr,
input wire [DATA_WIDTH - 1:0] din,
output reg [DATA_WIDTH - 1:0] dout
);
// Shared memory
localparam RAM_DEPTH = 2 ** ADDR_WIDTH;
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram [RAM_DEPTH-1:0];
integer i;
initial
begin
for(i=0; i
module bram_sdp #
(
parameter DATA_WIDTH = 8,
parameter ADDR_WIDTH = 11
)
(
// Port A
input wire clka,
input wire ena,
input wire wea,
input wire [ADDR_WIDTH-1:0] addra,
input wire [DATA_WIDTH-1:0] dina,
// Port B
input wire clkb,
input wire enb,
input wire [ADDR_WIDTH-1:0] addrb,
output reg [DATA_WIDTH-1:0] doutb = 0
);
// Shared memory
localparam RAM_DEPTH = 2 ** ADDR_WIDTH;
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram [RAM_DEPTH-1:0];
integer i;
initial
begin
for(i=0; i
module bram_tdp #
(
parameter DATA_WIDTH = 8,
parameter ADDR_WIDTH = 11,
parameter PORTA_MODE = "NO_CHANGE", //WRITE_FIRST, READ_FIRST or NO_CHANGE
parameter PORTB_MODE = "NO_CHANGE" //WRITE_FIRST, READ_FIRST or NO_CHANGE
)
(
// Port A
input wire clka,
input wire ena,
input wire wea,
input wire [ADDR_WIDTH-1:0] addra,
input wire [DATA_WIDTH-1:0] dina,
output reg [DATA_WIDTH-1:0] douta,
// Port B
input wire clkb,
input wire enb,
input wire web,
input wire [ADDR_WIDTH-1:0] addrb,
input wire [DATA_WIDTH-1:0] dinb,
output reg [DATA_WIDTH-1:0] doutb
);
// Shared memory
localparam RAM_DEPTH = 2 ** ADDR_WIDTH;
(* ram_style = "block" *) reg [DATA_WIDTH-1:0] ram [RAM_DEPTH-1:0];
integer i;
initial
begin
for(i=0; i