在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资源来实现灵活的存储结构。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐