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

以上就是本文全部内容。

相关推荐
学习FPGA的电气小兴兴1 天前
基于FPGA的DDS信号发生器设计,生成频率可调的正弦波、三角波、锯齿波和方波
fpga开发·数字信号处理·fpga·vivado·dsp·dds·diy
szxinmai主板定制专家2 天前
Zynq MPSoC半导体高精度运动控制方案|FPGA硬件插补实现亚微米级伺服实时控制
人工智能·嵌入式硬件·fpga开发·zynq·运动控制·ethercat
星夜离尘562 天前
ILA 在线调试:Vivado 抓取片内信号与定位下板问题(附完整实操)
fpga开发
jz_ddk2 天前
[学习] 深入理解 USB 通信与 FPGA 实现:从协议到逻辑设计
学习·fpga开发·xilinx·usb2.0
星夜离尘563 天前
PWM 信号生成与呼吸灯:占空比控制、按键调光与舵机扩展(附完整 Verilog 实操)
fpga开发
zlinear数据采集卡3 天前
ZLinear DABM-D223 通信协议与软件开发全解析:从 USB CDC 到 DDS 波形输出
arm开发·嵌入式硬件·fpga开发·开源
LCMICRO-133108477463 天前
国产长芯微LD3092完全pin-pin替代LT3092,是一款可编程两端电流源
arm开发·单片机·嵌入式硬件·fpga开发·硬件工程·恒流源·lt3092
nuoxin1143 天前
BL-M8812CU3 无线 WiFi 模块-富利威
人工智能·嵌入式硬件·fpga开发·硬件工程·dsp开发
xiaojiaohuazi3 天前
基于Zynq UltraScale+ MPSoC的PL DDR4直写多NVMe条带阵列(RAID 0)与exFAT高速采集存储系统
fpga开发