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

以上就是本文全部内容。

相关推荐
ZPC82102 天前
docker 镜像备份
人工智能·算法·fpga开发·机器人
ZPC82102 天前
docker 使用GUI ROS2
人工智能·算法·fpga开发·机器人
tiantianuser2 天前
RDMA设计53:构建RoCE v2 高速数据传输系统板级测试平台2
fpga开发·rdma·高速传输·cmac·roce v2
博览鸿蒙2 天前
FPGA 和 IC,哪个前景更好?怎么选?
fpga开发
FPGA_小田老师2 天前
xilinx原语:ISERDESE2原语详解(串并转换器)
fpga开发·iserdese2·原语·串并转换
tiantianuser2 天前
RDMA设计50: 如何验证网络嗅探功能?
网络·fpga开发·rdma·高速传输·cmac·roce v2
Lzy金壳bing2 天前
基于Vivado平台对Xilinx-7K325t FPGA芯片进行程序在线更新升级
fpga开发·vivado·xilinx
unicrom_深圳市由你创科技2 天前
医疗设备专用图像处理板卡定制
图像处理·人工智能·fpga开发
tiantianuser3 天前
RDMA设计52:构建RoCE v2 高速数据传输系统板级测试平台
fpga开发·rdma·高速传输·cmac·roce v2
luoganttcc3 天前
Taalas 将人工智能模型蚀刻到晶体管上,以提升推理能力
人工智能·fpga开发