Verilog 文件操作:$readmemh和$readmemb的使用

本文介绍了Verilog中的$readmemh和$readmemb指令用于从文件读取数据到寄存器数组或存储器,讨论了三种使用格式:不指定地址、指定起始地址和指定起止地址。还解释了地址表示方法及数组和存储器变量的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

$readmemh和$readmemb是两个系统,被用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了可以在仿真的任何时刻被执行使用外,根据综合工具的不同,也可以用来对RAM或者ROM进行初始化(Vivado支持)。

$readmemh中的h表示十六进制。

$readmemb中的b表示二进制。

使用格式如下,以$readmemb为例,$readmemh相同:

  • $readmemb(“数据文件名”,数组型/存储器型变量)

  • $readmemb (“数据文件名”,数组型/存储器型变量,变量的起始地址

  • $readmemb (“数据文件名”,数组型/存储器型变量,变量的起始地址,变量的结束地址)

    数据文件名:

    可以读取txt、v等格式文件。文件的数据必须是二进制和十六进制,而不是说会将文件里的数据转换成二进制和十六进制。

    地址写相对地址或绝对地址。但一定注意地址需要使用反斜杠 / 来表示层级。

    例如绝对路径: **$readmemh(“F:/test/data.txt”,mem_test); **

    相对地址是相对与工程位置的XX.sim\sim_1\behav\xsim‪的文件夹位置。直接将数据文件放入该文件夹地址内则 **$readmemh(“data.txt”,mem_test); **

三种使用格式解读

1、不指定变量地址

即:$readmemh(“F:/test/data.txt”,mem_test);

设reg [7:0] mem_test [9:0]; 数据被依次对应变量的最小地址开始填写,即第一个数据放入mem_test[0],第二个数据放入mem_test[1]直到放到mem_test[9],如果文件中没有十个数则后面的不被赋值。

设reg [7:0] mem_test [9:1]; 数据被依次对应变量的最小地址开始填写,即第一个数据放入mem_test[1],第二个数据放入mem_test[2]直到放到mem_test[9],如果文件中没有九个数则后面的不被赋值。

若reg [7:0] mem_test [9:0];和reg [7:0] mem_test [0:9];中9和0的书写顺序不一样,但读文件的顺序仍是先放入mem_test[0]的顺序。即[9:0]和 [0:9]不影响每个mem_test 的值,其他使用格式同样遵循。

2、只指定变量起始地址

即:$readmemh(“F:/test/data.txt”,mem_test,3);

设reg [7:0] mem_test [9:0]; 则前面0,1,2不被赋值,第一个数据放入mem_test[3],依次类推。

3、同时指定变量的起始地址和结束地址

即:$readmemh(“F:/test/data.txt”,mem_test,3,8);

设reg [7:0] mem_test [9:0]; 则前面0,1,2,9不被赋值,第一个数据放入mem_test[3],依次类推到mem_test[8]。

参考资料

本文大部分总结于前辈博客,只给出结论,若要代码验证请参看http://t.csdn.cn/R5smI

补充:什么是数组和存储器变量

什么是数组和存储器变量

在这里插入图片描述

在这里插入图片描述

<think>嗯,用户想了解Verilog$readmemh的用法。我需要先回忆一下这个系统任务的基本功能。$readmemh应该是用来从文件中读取十六进制数据到内存数组中的。用户可能是在做FPGA或ASIC设计时需要初始化存储器,所以需要了解如何使用这个函数。 首先,我应该解释$readmemh的作用,比如它用于将十六进制数据加载到寄存器或内存数组中。然后需要说明语法结构,参数包括文件名、数组名、起始地址结束地址,后面两个是可选的。可能需要给出一个简单的例子,比如声明一个数组,然后用$readmemh读取数据。 接下来要注意的是文件格式。用户需要知道数据文件的结构,每行一个十六进制数,可能支持注释,比如//或者#开头的行。要提醒用户注意文件路径是否正确,相对路径绝对路径的区别,以及仿真器的工作目录问题。 然后,地址范围的使用。如果用户指定了起始结束地址,数据会按顺序填充到这些地址中。如果不指定,就从头到尾填充数组。这里可能需要举例说明不同情况下的加载方式。 还要提到常见的错误,比如文件未找到、数据格式错误、数组大小不匹配等。这些是用户在实际使用中可能会遇到的问题,给出提示可以帮助他们调试。 另外,是否需要区分$readmemh$readmemb?可能用户会混淆这两个,所以可以简单对比,说明前者是十六进制,后者是二进制。 最后,应用场景,比如ROM初始化、测试数据加载等,让用户知道在什么情况下使用这个函数比较合适。 要确保语言清晰,结构分明,步骤注意事项分点列出,方便用户理解。可能需要用代码示例来展示正确的用法,同时强调语法中的细节,比如数组的位宽匹配,文件中的数据位数是否与数组每个元素位宽一致。 现在检查是否有遗漏点,比如是否支持多维数组?可能Verilog中的内存数组是一维的,所以$readmemh也只能用于一维数组。需要指出这一点,避免用户错误使用在多维数组上。 还有,数据加载的时机,应该是在仿真开始时就加载,所以通常在initial块中使用。可能需要在示例中展示initial块中的调用。 总结一下,回答的结构应该是:作用、语法、文件格式、地址参数、示例、注意事项、应用场景、常见问题。这样用户能逐步了解并正确使用$readmemh。</think>Verilog中`$readmemh`的用法详解 --- ### 1. **基本作用** `$readmemh`是Verilog中的系统任务,用于将**十六进制数据文件**加载到寄存器或内存数组中。常用于仿真时初始化ROM、RAM或测试数据。 --- ### 2. **语法格式** ```verilog $readmemh("文件路径", 数组名 [, 起始地址 [, 结束地址]]); ``` - **参数说明**: - `文件路径`:字符串,指定数据文件路径(如`"data.txt"`) - `数组名`:目标内存数组的名称 - `起始地址``结束地址`:可选参数,指定加载数据的地址范围 --- ### 3. **数据文件格式要求** - 每行一个十六进制数,例如: ``` 1A // 地址0 2B // 地址1 3C_3F // 下划线提高可读性(Verilog 2001+支持) // 注释以//或#开头 ``` - **注意事项**: - 数据位宽需与数组元素位宽匹配 - 支持`_`分隔符(如`12AB_CDEF`) - 忽略空行注释行 --- ### 4. **代码示例** #### 示例1:基础用法 ```verilog reg [7:0] mem [0:3]; // 声明4个8位存储单元 initial begin $readmemh("data.txt", mem); // 加载全部数据 end ``` #### 示例2:指定地址范围 ```verilog reg [31:0] buffer [0:255]; initial begin // 仅加载数据到地址10~20 $readmemh("input.hex", buffer, 10, 20); end ``` --- ### 5. **注意事项** 1. **文件路径**: - 相对路径相对于仿真器工作目录 - 推荐使用绝对路径避免路径错误 2. **数组声明**: - 数组必须静态声明(大小固定) - 数据位宽必须匹配,如声明`reg [15:0] mem [0:7]`需要每个数据为4位十六进制(如`3F8A`) 3. **错误处理**: - 文件未找到:静默失败(不会报错,但数组保持原值) - 数据过多:截断多余数据 - 数据不足:剩余地址保持未初始化 --- ### 6. **典型应用场景** - FPGA中初始化Block RAM - 存储测试向量(如滤波器系数、图像数据) - 模拟CPU指令加载 --- ### 7. **对比`$readmemb`** | 任务 | 数据格式 | 示例数据 | |-------------|------------|---------------| | `$readmemh` | 十六进制 | `A3`, `1F` | | `$readmemb` | 二进制 | `1010_1101` | --- ### 8. **调试建议** - 使用`$display`验证加载结果: ```verilog initial begin $readmemh("data.hex", mem); for (int i=0; i<4; i++) $display("mem[%0d] = %h", i, mem[i]); end ``` 通过以上步骤,您可以可靠地初始化Verilog内存数组。实际使用时需特别注意文件路径位宽匹配问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值