一种无需IP核的FPGA RAM初始化方法:基于源码定义与赋值实现

          \;\;\;\;\; 在FPGA设计中,许多人仍习惯用RAM IP核来初始化存储数据,但每次修改初始化文件或参数都要重新生成IP,会降低效率。其实,我们可以直接在Verilog代码中定义并初始化RAM,让综合工具自动推断出对应的块RAM或分布式RAM。这种方式灵活、便于维护。本文将介绍这种更灵活的RAM初始化方式。

一、在源代码中定义并初始化RAM

          \;\;\;\;\; 在Verilog代码中,我们可以定义一个RAM数组,然后在initial块中为数组加载初始数据。这样综合工具会自动识别为块RAM或分布式RAM结构,实现"代码生成并初始化RAM",无需再依赖IP核。

          \;\;\;\;\; 例如下面是通过代码写的一个深度为16,宽度为8的RAM,并为其初始化了存储阵列的数据。we信号是读写选择信号,0读1写。en是高电平使能信号。

bash 复制代码
module rams_sp_rom (clk, we, addr, di, dout, en);
input clk;
input we;
input [3:0] addr;
input [7:0] di;
input en;
output [7:0] dout;
reg [7:0] ram [15:0];
reg [7:0] dout=0;

initial
begin
    ram[15] = 8'h02; ram[14] = 8'h21; ram[13] = 8'h03;
    ram[12] = 8'h01; ram[11] = 8'h01; ram[10] = 8'h23;
    ram[9]  = 8'h04; ram[8]  = 8'h03; ram[7]  = 8'h04;
    ram[6]  = 8'h00; ram[5]  = 8'h25; ram[4]  = 8'h50;
    ram[3]  = 8'h0D; ram[2]  = 8'h23; ram[1]  = 8'h20;
    ram[0]  = 8'h0D;
end

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

endmodule

          \;\;\;\;\; 下图是读仿真的结果。因为这个位宽深度都比较小,综合出来的就是分布式RAM结构。

          \;\;\;\;\; 下图是综合的电路的结果。

          \;\;\;\;\; 善于思考的读者读到这里,想必已经知道如何以同样的操作生成ROM了吧,只需要在上面的端口去掉写相关的端口即可。

          \;\;\;\;\; 另外,如果想对RAM的存储阵列全部赋初值为0,使用下面的initial块即可。

bash 复制代码
integer i;
initial 
begin
for (i=0; i<16; i=i+1) ram[i] = 0;
end

二、在源代码中定义并在文件中初始化RAM

          \;\;\;\;\; 可直接将数据以二进制个数写入txt文件,如下图所示。

          \;\;\;\;\; 以下代码生成的一个深度和位宽均为8的RAM。代码中将文件路径替换成自己的即可。

bash 复制代码
module rams_init_file (clk, we, addr, din, dout, en);
input clk;
input we;
input [7:0] addr;
input [7:0] din;
input en;
output [7:0] dout;
reg [7:0] ram [0:255];
reg [7:0] dout=0;

initial begin
$readmemb("文件路径/ramdata.txt",ram);
end

always @(posedge clk)
begin
    if(en)
        begin
            if (we)
            ram[addr] <= din;
            dout <= ram[addr];
        end 
end

endmodule

          \;\;\;\;\; 下图是读仿真的结果,这个综合出来的就是块RAM结构。

          \;\;\;\;\; 下图是综合的电路的结果。

          \;\;\;\;\; 当然,也可以通过综合属性指定生成的RAM类型,有以下一些类型。

          \;\;\;\;\; 比如在前面的代码中如果写成如下形式,那么就是明确要求综合器综合出块RAM。

bash 复制代码
(* ram_style = "distributed" *) reg [7:0] ram [0:255];

以上就是本文全部内容。

相关推荐
2601_961845421 天前
2027考研数学大纲|数一数二数三
考研·fpga开发·ar·vr·mr·oneflow
X_xcccc1 天前
2026年嵌入式智能核心,从异构计算到敏捷开发的硬核指南
fpga开发·敏捷流程·zynq-7000·fpga板卡定制
9527华安1 天前
FPGA实现GTX Transceivers Wizard传输2路视频,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
fpga开发·aurora·gtx·高速接口·高速收发器·transceivers
ALINX技术博客1 天前
【黑金云课堂】FPGA技术教程Linux开发:摄像头GPU渲染显示/Qt OpenGLES使用
linux·qt·fpga开发·gpu
S&Z34631 天前
SZ901下载器烧写国产Flash指南
fpga开发
liuluyang5301 天前
Verilog-1995风格,reg变量声明两次
fpga开发
cjie2211 天前
安路好用的调试工具VPI
fpga开发
chenlance2 天前
基于FPGA的激光器多通道数据采集与波形控制系统设计
fpga开发
9527华安2 天前
FPGA实现GTP高速收发器2路视频传输,基于aurora 8b10b编解码架构,提供4套工程源码和技术支持
图像处理·fpga开发·aurora·高速收发器·8b10b·derdes
cjie2212 天前
lanczos插值引起的振铃现象
计算机视觉·fpga开发