iCE40 FPGA 中的级联 BRAM
Cascading BRAM in iCE40 FPGA
我对 FPGA 和 Verilog 真的很陌生。我一直在研究控制 Noritake Itron VFD 显示器的 Tri-SPI PHY。我想要实现的功能之一是 FPGA 本身的帧缓冲存储器。我正在使用具有 64kbit BRAM(8Kbytes)的 iCE40LP1K。但是 Verilog BRAM 原语是 4kbit,我需要 3003 字节的缓冲区。
问题是如何级联 BRAM?在数据表中(参考 iCE40 LP/HX Family Data Sheet,第 2-6 页)提到了使用多个 BRAM。有没有办法可以使用 SB_RAM40_4K 的多个实例?然后将其视为一个大型内存数组。
通常,您会使用 FPGA 制造商提供的一些工具。您有一些向导可以实例化您需要的 IP 是很常见的(甚至可能是理所当然的)。
在这样的 wizard/editor/generator 中,您将 select 您需要的内存类型(single/dual 端口、宽度、深度等),并且该工具将生成实例化的文件所需的硬件块。该向导负责以最佳方式执行此操作,例如使用最小宽度和最大深度拼接 ram 块,以最大程度地减少多路复用器上浪费的元素数量。
我能够如愿以偿地使用BRAM。原来我只是将寄存器声明为8位数组。只需确保该寄存器数组有输入和输出 to/from。因为我需要 3004 字节,下面的代码是我如何让它工作的:(注意:名称并不重要,Yosys 足够聪明,可以映射到 SB_RAM40_4k。您还可以更改数组大小和地址位宽)。
module BRAM(
input R_CLK,
input W_CLK,
input [7:0]BRAM_IN,
output reg [7:0]BRAM_OUT,
input [11:0] BRAM_ADDR_R,
input [11:0] BRAM_ADDR_W,
input B_CE_W,
input B_CE_R);
reg [7:0] mem [3003:0];
always@(posedge R_CLK) begin// reading from RAM sync with system clock
if(!B_CE_R)
BRAM_OUT <= mem[BRAM_ADDR_R];
end
always@(posedge W_CLK) begin// writing to RAM sync with Slave SPI clock.
if(!B_CE_W)
mem[BRAM_ADDR_W] <= BRAM_IN;
end
endmodule
我对 FPGA 和 Verilog 真的很陌生。我一直在研究控制 Noritake Itron VFD 显示器的 Tri-SPI PHY。我想要实现的功能之一是 FPGA 本身的帧缓冲存储器。我正在使用具有 64kbit BRAM(8Kbytes)的 iCE40LP1K。但是 Verilog BRAM 原语是 4kbit,我需要 3003 字节的缓冲区。
问题是如何级联 BRAM?在数据表中(参考 iCE40 LP/HX Family Data Sheet,第 2-6 页)提到了使用多个 BRAM。有没有办法可以使用 SB_RAM40_4K 的多个实例?然后将其视为一个大型内存数组。
通常,您会使用 FPGA 制造商提供的一些工具。您有一些向导可以实例化您需要的 IP 是很常见的(甚至可能是理所当然的)。
在这样的 wizard/editor/generator 中,您将 select 您需要的内存类型(single/dual 端口、宽度、深度等),并且该工具将生成实例化的文件所需的硬件块。该向导负责以最佳方式执行此操作,例如使用最小宽度和最大深度拼接 ram 块,以最大程度地减少多路复用器上浪费的元素数量。
我能够如愿以偿地使用BRAM。原来我只是将寄存器声明为8位数组。只需确保该寄存器数组有输入和输出 to/from。因为我需要 3004 字节,下面的代码是我如何让它工作的:(注意:名称并不重要,Yosys 足够聪明,可以映射到 SB_RAM40_4k。您还可以更改数组大小和地址位宽)。
module BRAM(
input R_CLK,
input W_CLK,
input [7:0]BRAM_IN,
output reg [7:0]BRAM_OUT,
input [11:0] BRAM_ADDR_R,
input [11:0] BRAM_ADDR_W,
input B_CE_W,
input B_CE_R);
reg [7:0] mem [3003:0];
always@(posedge R_CLK) begin// reading from RAM sync with system clock
if(!B_CE_R)
BRAM_OUT <= mem[BRAM_ADDR_R];
end
always@(posedge W_CLK) begin// writing to RAM sync with Slave SPI clock.
if(!B_CE_W)
mem[BRAM_ADDR_W] <= BRAM_IN;
end
endmodule