一种无需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];

以上就是本文全部内容。

相关推荐
碎碎思2 小时前
KRS(Kratos Robotics Stack):让 Zynq / FPGA 机器人开发真正“跑”起来
fpga开发·机器人
Terasic友晶科技4 小时前
Altera FPGA 的 Avalon MM总线接口规范介绍(精简版)
fpga开发·接口·sopc·avalon总线
啊阿狸不会拉杆4 小时前
《数字信号处理》第10章-数字信号处理中的有限字长效应
算法·matlab·fpga开发·信号处理·数字信号处理·dsp
雨洛lhw20 小时前
24bit AD采样高效数据打包方案解析
fpga开发·数据打包方式·ddr突发读写注意事项
XiaoChaoZhiNeng1 天前
Xilinx Vivado18.3 Modelsim 库编译与仿真
fpga开发
Flamingˢ1 天前
FPGA 显示系统学习路线:从 VGA 到 RGB TFT
学习·fpga开发
tiantianuser1 天前
RDMA设计37:RoCE v2 子系统模型设计
fpga开发·rdma·高速传输·cmac·roce v2
8K超高清1 天前
博冠8K广播级讯道摄像机获国际设计大奖
网络·算法·fpga开发·接口隔离原则·智能硬件
ooo-p2 天前
FPGA学习篇——Verilog学习之“呼吸灯”
学习·fpga开发
雨洛lhw2 天前
STFT性能测试记录笔记(verilog )
fpga开发