在Verilog/SystemVerilog中,(* ram_style = "distributed" *) 是一个综合实现属性,用于指导综合工具将存储器推断为分布式RAM(Distributed RAM)而不是块RAM或寄存器。
一、语法和作用
(* ram_style = "distributed" *) reg [width-1:0] memory [0:depth-1];
二、主要用途和特点
1. 分布式RAM的基本用法
module distributed_ram_example (
input wire clk,
input wire we,
input wire [4:0] addr, // 32深度
input wire [7:0] din, // 8位宽度
output reg [7:0] dout
);
(* ram_style = "distributed" *) reg [7:0] dist_ram [0:31];
always @(posedge clk) begin
if (we)
dist_ram[addr] <= din;
dout <= dist_ram[addr];
end
endmodule
2. 分布式RAM vs 块RAM对比
module ram_comparison (
input wire clk,
input wire we,
input wire [5:0] addr,
input wire [15:0] din,
output wire [15:0] dout_dist, dout_block
);
// 分布式RAM - 使用LUT资源实现
(* ram_style = "distributed" *) reg [15:0] dist_ram [0:63];
// 块RAM - 使用专用RAM资源
(* ram_style = "block" *) reg [15:0] block_ram [0:63];
always @(posedge clk) begin
if (we) begin
dist_ram[addr] <= din;
block_ram[addr] <= din;
end
end
assign dout_dist = dist_ram[addr];
assign dout_block = block_ram[addr];
endmodule
三、分布式RAM的优势场景
1. 小容量多端口存储器
module multi_port_dist_ram (
input wire clk,
input wire we_a, we_b,
input wire [3:0] addr_a, addr_b, addr_c,
input wire [7:0] din_a, din_b,
output reg [7:0] dout_a, dout_b, dout_c
);
(* ram_style = "distributed" *) reg [7:0] ram [0:15];
always @(posedge clk) begin
// 多个写端口(需要冲突解决)
if (we_a)
ram[addr_a] <= din_a;
else if (we_b)
ram[addr_b] <= din_b;
// 多个读端口
dout_a <= ram[addr_a];
dout_b <= ram[addr_b];
dout_c <= ram[addr_c];
end
endmodule
2. 异步读出的分布式RAM
module async_read_dist_ram (
input wire clk,
input wire we,
input wire [4:0] waddr, raddr,
input wire [31:0] din,
output wire [31:0] dout_async,
output reg [31:0] dout_sync
);
(* ram_style = "distributed" *) reg [31:0] ram [0:31];
// 同步写
always @(posedge clk) begin
if (we)
ram[waddr] <= din;
end
// 异步读 - 分布式RAM支持
assign dout_async = ram[raddr];
// 同步读
always @(posedge clk) begin
dout_sync <= ram[raddr];
end
endmodule
3. 可变宽度的分布式RAM
module variable_width_dist_ram (
input wire clk,
input wire we,
input wire [1:0] width_sel, // 00=8bit, 01=16bit, 10=32bit
input wire [7:0] addr,
input wire [31:0] din,
output reg [31:0] dout
);
(* ram_style = "distributed" *) reg [31:0] ram [0:255];
reg [31:0] write_mask;
always @(*) begin
case (width_sel)
2'b00: write_mask = 32'h000000FF;
2'b01: write_mask = 32'h0000FFFF;
2'b10: write_mask = 32'hFFFFFFFF;
default: write_mask = 32'h000000FF;
endcase
end
always @(posedge clk) begin
if (we)
ram[addr] <= din & write_mask;
dout <= ram[addr] & write_mask;
end
endmodule
四、实际应用场景
1. 查找表(LUT)实现
module lut_based_design (
input wire clk,
input wire [3:0] addr,
input wire [7:0] config_data,
input wire config_en,
output wire [15:0] result
);
// 可配置的查找表 - 使用分布式RAM
(* ram_style = "distributed" *) reg [15:0] lookup_table [0:15];
// 初始化LUT内容
initial begin
lookup_table[0] = 16'h0001;
lookup_table[1] = 16'h0004;
lookup_table[2] = 16'h0010;
lookup_table[3] = 16'h0040;
// ... 其他初始化
lookup_table[15] = 16'h8000;
end
// 运行时配置
always @(posedge clk) begin
if (config_en)
lookup_table[addr] <= {8'h00, config_data};
end
assign result = lookup_table[addr];
endmodule
2. 小容量FIFO
module small_fifo_dist_ram (
input wire clk,
input wire rst,
input wire wr_en, rd_en,
input wire [7:0] din,
output wire [7:0] dout,
output wire full, empty
);
parameter DEPTH = 16;
parameter WIDTH = 8;
(* ram_style = "distributed" *) reg [WIDTH-1:0] fifo_ram [0:DEPTH-1];
reg [3:0] wr_ptr, rd_ptr;
reg [4:0] count;
assign full = (count == DEPTH);
assign empty = (count == 0);
assign dout = fifo_ram[rd_ptr];
always @(posedge clk) begin
if (rst) begin
wr_ptr <= 0;
rd_ptr <= 0;
count <= 0;
end else begin
// 写操作
if (wr_en && !full) begin
fifo_ram[wr_ptr] <= din;
wr_ptr <= wr_ptr + 1;
end
// 读操作
if (rd_en && !empty) begin
rd_ptr <= rd_ptr + 1;
end
// 更新计数器
case ({wr_en && !full, rd_en && !empty})
2'b10: count <= count + 1;
2'b01: count <= count - 1;
default: count <= count;
endcase
end
end
endmodule
五、工具支持
-
Xilinx Vivado: 完全支持
-
Intel Quartus: 使用
ramstyle = "MLAB"或ramstyle = "logic" -
Synopsys Design Compiler: 支持
-
其他FPGA工具: 通常都支持分布式RAM属性
六、使用建议和最佳实践
1. 容量选择指南
module capacity_guideline (
input wire clk,
input wire we,
input wire [7:0] addr_small, addr_medium, addr_large,
input wire [31:0] din,
output reg [31:0] dout_small, dout_medium, dout_large
);
// 小容量(< 64位):适合分布式RAM
(* ram_style = "distributed" *) reg [31:0] small_ram [0:15]; // 16x32 = 512 bit
// 中等容量(64-2K位):根据需求选择
(* ram_style = "distributed" *) reg [31:0] medium_ram [0:31]; // 32x32 = 1024 bit
// 大容量(> 2K位):适合块RAM
(* ram_style = "block" *) reg [31:0] large_ram [0:255]; // 256x32 = 8192 bit
always @(posedge clk) begin
if (we) begin
small_ram[addr_small[3:0]] <= din;
medium_ram[addr_medium[4:0]] <= din;
large_ram[addr_large] <= din;
end
dout_small <= small_ram[addr_small[3:0]];
dout_medium <= medium_ram[addr_medium[4:0]];
dout_large <= large_ram[addr_large];
end
endmodule
七、属性取值对比
(* ram_style = "distributed" *) // 分布式RAM(LUT资源,小容量,低延迟) (* ram_style = "block" *) // 块RAM(专用资源,大容量,固定延迟) (* ram_style = "registers" *) // 寄存器(最大灵活性,最高资源消耗) (* ram_style = "auto" *) // 工具自动选择
八、分布式RAM的特点总结
1. 优点
-
低访问延迟(通常1个周期)
-
支持异步读取
-
支持多端口访问
-
灵活的实现方式
2. 缺点
-
容量有限(消耗LUT资源)
-
资源利用率可能不高
-
不适合大容量存储
3. 适用场景
-
小容量存储器(< 1-2Kb)
-
需要多端口访问的存储器
-
需要异步读出的应用
-
查找表(LUT)实现
-
小容量FIFO、缓存等
这个属性在需要低延迟、多端口或小容量存储的应用中非常有用,可以充分利用FPGA的LUT资源来实现灵活的存储结构。
2496

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



