You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vivado中同周期写入12个地址且被识别为BRAM

问题:实现12×14结构RAM的单周期整列写入并映射为BRAM

以下是原本可被综合为BRAM的RAM代码:

module RAM_IMAGINARY (clk, we, en, addr, di, dout);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout;
logic [15:0] RAM_IMAGINARY [167:0];
logic [15:0] dout;
always @(posedge clk)
begin
if (en)begin
if (we) begin
  RAM_IMAGINARY[addr] <= di;
  dout <= di;
end
else
dout <= RAM_IMAGINARY[addr];
end
end
endmodule      

需求是将RAM视为12×14的二维结构,实现单周期写入整列数据。曾尝试例化12个小容量RAM并行写入,但因每个RAM的深度(14)和宽度(16bit)过小,未被工具识别为BRAM,相关代码如下:

小容量RAM模块

module RAM_IMAGINARY (clk, we, en, addr, di, dout);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout;
logic [15:0] RAM_IMAGINARY [13:0];
logic [15:0] dout;
always @(posedge clk)
begin
if (en)begin
if (we) begin
RAM_IMAGINARY[addr] <= di;
dout <= di;
end
else
dout <= RAM_IMAGINARY[addr];
end
end
endmodule

顶层例化模块

module Top(clk, we, en, addr, di, dout0,dout1,dout2,dout3,dout4,dout5,dout6,dout7,dout8,dout9,dout10,dout11);
input clk;
input we;
input en;
input [7:0] addr;
input [15:0] di;
output [15:0] dout0,dout1,dout2,dout3,dout4,dout5,dout6,dout7,dout8,dout9,dout10,dout11;
RAM_IMAGINARY RAM0 (clk, we, en, addr, di, dout0) ;
RAM_IMAGINARY RAM1 (clk, we, en, addr, di, dout1) ;
RAM_IMAGINARY RAM2 (clk, we, en, addr, di, dout2) ;
RAM_IMAGINARY RAM3 (clk, we, en, addr, di, dout3) ;
RAM_IMAGINARY RAM4 (clk, we, en, addr, di, dout4) ;
RAM_IMAGINARY RAM5 (clk, we, en, addr, di, dout5) ;
RAM_IMAGINARY RAM6 (clk, we, en, addr, di, dout6) ;
RAM_IMAGINARY RAM7 (clk, we, en, addr, di, dout7) ;
RAM_IMAGINARY RAM8 (clk, we, en, addr, di, dout8) ;
RAM_IMAGINARY RAM9 (clk, we, en, addr, di, dout9) ;
RAM_IMAGINARY RAM10 (clk, we, en, addr, di, dout10) ;
RAM_IMAGINARY RAM11 (clk, we, en, addr, di, dout11) ;
endmodule

解决方案

方案1:合并为大容量RAM(推荐)

将12×14的二维结构转换为**深度14、位宽192bit(12×16bit)**的单块RAM,单周期写入一个地址即可完成整列12个数据的写入,总容量为14×192=2688bit,完全符合BRAM的资源阈值,会被工具自动识别为BRAM。

代码示例:

module RAM_COLUMN_WRITE (
    clk,
    we,
    en,
    addr,
    di,
    dout
);
input clk;
input we;
input en;
input [3:0] addr;  // 14列对应地址0-13,4bit足够
input [191:0] di;  // 12个16bit数据拼接:di[191:176]为第11个,di[15:0]为第0个
output [191:0] dout;

logic [191:0] RAM [13:0];  // 深度14,位宽192bit
logic [191:0] dout;

always @(posedge clk) begin
    if (en) begin
        if (we) begin
            RAM[addr] <= di;
            dout <= di;
        end else begin
            dout <= RAM[addr];
        end
    end
end
endmodule

若需要单独访问单个16bit数据,可直接拆分dout信号,例如assign dout0 = dout[15:0];、assign dout1 = dout[31:16];等。

方案2:强制小RAM映射为BRAM

若必须保留12个独立RAM的结构,可通过添加Synopsys属性(* ram_style = "block" *)强制工具将小RAM映射为BRAM,忽略容量阈值限制。

修改后的小RAM模块代码:

module RAM_IMAGINARY (clk, we, en, addr, di, dout);
input clk;
input we;
input en;
input [3:0] addr;  // 优化地址位宽,深度14仅需4bit
input [15:0] di;
output [15:0] dout;
(* ram_style = "block" *) logic [15:0] RAM_IMAGINARY [13:0];  // 强制映射为BRAM
logic [15:0] dout;

always @(posedge clk)
begin
if (en)begin
if (we) begin
RAM_IMAGINARY[addr] <= di;
dout <= di;
end
else
dout <= RAM_IMAGINARY[addr];
end
end
endmodule

注意:此方案会浪费BRAM资源(单个BRAM可容纳多个小RAM),仅在必须保留独立RAM结构时使用。

方案3:使用FPGA厂商IP核

直接调用Vivado的Block Memory Generator IP核,配置为深度14、位宽192bit的单端口RAM,可确保100%映射为BRAM,同时支持输出寄存器、写保护等定制化功能,适合复杂场景。


内容的提问来源于stack exchange,提问作者WithaSpirit1234

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 06:43:15