在Verilog/SystemVerilog中,(* ram_style = "block" *) 是一个综合实现属性,用于指导综合工具将存储器推断为块RAM(Block RAM)而不是分布式RAM或寄存器。
一、语法和作用
(* ram_style = "block" *) reg [width-1:0] memory [0:depth-1];
二、主要用途和对比
1. 块RAM vs 分布式RAM
module memory_example (
input wire clk,
input wire we,
input wire [7:0] addr,
input wire [31:0] din,
output reg [31:0] dout
);
// 使用块RAM - 大容量,专用硬件资源
(* ram_style = "block" *) reg [31:0] block_ram [0:255]; // 256x32-bit
// 使用分布式RAM - 小容量,使用LUT资源
(* ram_style = "distributed" *) reg [31:0] distributed_ram [0:15]; // 16x32-bit
always @(posedge clk) begin
if (we) begin
block_ram[addr] <= din;
if (addr[7:4] == 4'b0)
distributed_ram[addr[3:0]] <= din;
end
dout <= block_ram[addr];
end
endmodule
2. 单端口RAM的块RAM实现
module single_port_ram (
input wire clk,
input wire we,
input wire [9:0] addr, // 1K深度
input wire [15:0] din, // 16位宽度
output reg [15:0] dout
);
(* ram_style = "block" *) reg [15:0] ram [0:1023];
always @(posedge clk) begin
if (we)
ram[addr] <= din;
dout <= ram[addr];
end
endmodule
3. 真双端口RAM
module true_dual_port_ram (
input wire clk_a, clk_b,
input wire we_a, we_b,
input wire [8:0] addr_a, addr_b, // 512深度
input wire [31:0] din_a, din_b,
output reg [31:0] dout_a, dout_b
);
(* ram_style = "block" *) reg [31:0] ram [0:511];
// 端口A
always @(posedge clk_a) begin
if (we_a)
ram[addr_a] <= din_a;
dout_a <= ram[addr_a];
end
// 端口B
always @(posedge clk_b) begin
if (we_b)
ram[addr_b] <= din_b;
dout_b <= ram[addr_b];
end
endmodule
4. 简单双端口RAM(一个写端口,一个读端口)
module simple_dual_port_ram (
input wire clk,
input wire we,
input wire [8:0] waddr, raddr,
input wire [7:0] din,
output reg [7:0] dout
);
(* ram_style = "block" *) reg [7:0] ram [0:511];
always @(posedge clk) begin
if (we)
ram[waddr] <= din;
dout <= ram[raddr];
end
endmodule
5. 带字节使能的块RAM
module byte_enable_ram (
input wire clk,
input wire we,
input wire [3:0] byte_en, // 字节使能
input wire [9:0] addr,
input wire [31:0] din,
output reg [31:0] dout
);
(* ram_style = "block" *) reg [31:0] ram [0:1023];
reg [31:0] ram_read;
always @(posedge clk) begin
ram_read <= ram[addr];
if (we) begin
if (byte_en[0]) ram[addr][7:0] <= din[7:0];
if (byte_en[1]) ram[addr][15:8] <= din[15:8];
if (byte_en[2]) ram[addr][23:16] <= din[23:16];
if (byte_en[3]) ram[addr][31:24] <= din[31:24];
end
dout <= ram_read;
end
endmodule
6. ROM的块RAM实现
module rom_block (
input wire clk,
input wire [7:0] addr,
output reg [15:0] dout
);
(* ram_style = "block" *) reg [15:0] rom [0:255];
// 初始化ROM内容
initial begin
$readmemh("rom_data.hex", rom);
end
always @(posedge clk) begin
dout <= rom[addr];
end
endmodule
三、工具支持
-
Xilinx Vivado: 完全支持
-
Intel Quartus: 使用
ramstyle = "M9K"或ramstyle = "M20K" -
Synopsys Design Compiler: 支持
-
其他FPGA工具: 通常都支持类似的RAM样式属性
四、不同RAM样式对比
1. RAM样式选择示例
module ram_style_comparison (
input wire clk,
input wire [1:0] style_sel,
input wire we,
input wire [7:0] addr,
input wire [31:0] din,
output reg [31:0] dout
);
// 根据选择使用不同的RAM样式
(* ram_style = (style_sel == 0) ? "block" :
(style_sel == 1) ? "distributed" : "registers" *)
reg [31:0] memory [0:255];
always @(posedge clk) begin
if (we)
memory[addr] <= din;
dout <= memory[addr];
end
endmodule
五、使用建议和最佳实践
1. 根据容量选择RAM样式
module optimized_memory_design (
input wire clk,
input wire we_small, we_large,
input wire [5:0] small_addr, // 小容量 - 分布式RAM
input wire [10:0] large_addr, // 大容量 - 块RAM
input wire [15:0] din,
output reg [15:0] dout_small, dout_large
);
// 小容量存储器使用分布式RAM(< 64位)
(* ram_style = "distributed" *) reg [15:0] small_ram [0:63];
// 大容量存储器使用块RAM(> 64位)
(* ram_style = "block" *) reg [15:0] large_ram [0:2047];
always @(posedge clk) begin
if (we_small)
small_ram[small_addr] <= din;
dout_small <= small_ram[small_addr];
if (we_large)
large_ram[large_addr] <= din;
dout_large <= large_ram[large_addr];
end
endmodule
六、属性取值
(* ram_style = "block" *) // 使用块RAM(大容量,专用资源) (* ram_style = "distributed" *) // 使用分布式RAM(小容量,LUT资源) (* ram_style = "registers" *) // 使用寄存器(极小容量,高性能) (* ram_style = "auto" *) // 由工具自动选择(默认)
七、注意事项
-
容量考虑 - 块RAM适合大容量存储(通常>64位),分布式RAM适合小容量
-
时序特性 - 块RAM有固定的流水线延迟,分布式RAM延迟较低
-
资源限制 - 块RAM数量有限,需要合理规划
-
工具兼容性 - 不同厂商的属性语法可能略有差异
-
验证必要 - 检查综合报告确认RAM是否正确推断
这个属性在FPGA设计中非常重要,可以帮助优化存储器的性能和资源使用效率。
3662

被折叠的 条评论
为什么被折叠?



