Verilog 文件操作

17 Mar 2025 | 6 分钟阅读

Verilog具有系统任务和函数,可以打开文件,将值输出到文件,从文件中读取值并加载到其他变量以及关闭文件。

此应用程序描述了Verilog模型或测试平台如何读取文本和二进制文件以加载存储器,应用激励并控制仿真。文件I / O功能的格式基于C stdio例程,例如fopen,fgetc,fprintffscanf

Verilog 语言有一组系统函数来写入文件($fdisplay,$fwrite 等),但只能以单一固定格式($readmem)读取文件。

过去,如果我们想读取一个不在$readmem格式的文件,我们必须学习编程语言接口 (PLI) 和 C 语言,编写 C 代码来读取文件并将值传递到 Verilog 中,然后调试组合的 C 和 Verilog 代码。 此外,Verilog 一次最多只能打开 32 个文件。

但是,使用新的文件 I/O 系统函数,我们可以直接从 Verilog 执行文件 I/O。 我们可以编写 Verilog HDL 来

  • 读取激励文件以将模式应用于模型的输入。
  • 读取预期值的文件,以便与您的模型进行比较。
  • 读取用于驱动仿真的命令脚本。
  • 将 ASCII 或二进制文件读入 Verilog 寄存器和存储器。
  • 同时打开数百个日志文件(尽管它们一次写入一个)。

此文件中所有示例的代码都包含在文件 I/O 函数的示例目录中。

注意:这些系统任务的行为与等效的 stdio 例程相同。 例如,$fscanf 将跳过空格,包括空行,就像 fscanf() 一样。 我们可以用 C 语言制作原型代码,然后将其转换为 Verilog。

打开和关闭文件

$fopen 函数打开一个文件,并以无大小整数格式返回一个多通道描述符。 这对于每个文件都是唯一的。 模拟器和文件之间的所有通信都通过文件描述符进行。 用户只能指定文件名作为参数。 它将在默认文件夹或完整路径描述中给定的文件夹中创建一个文件。

我们使用$fclose函数来关闭一个打开的文件。 此函数在调用时不带任何参数。 它只是关闭所有打开的文件。 如果指定了参数,它将仅关闭给出描述符的文件。 默认情况下,在模拟器终止之前,所有打开的文件都将被关闭。 这意味着用户不必关闭任何文件,并且关闭由模拟器自动完成。

所有文件输出任务的工作方式与它们对应的显示任务相同。 唯一的区别是文件描述符,它显示在函数参数列表中的第一个参数中。 这些函数只能将数据追加到文件中,而不能从文件中读取数据。

打开文件模式

参数描述
"r" 或 "rb"打开以进行读取。
"w" 或 "wb"创建一个新文件用于写入。 如果文件存在,则将其截断为零长度并覆盖它。
"a" 或 "ab"如果文件存在,则追加(打开以在 EOF 处写入),否则创建一个新文件。
"r+", "r+b" 或 "rb+"打开以进行读取和写入。
"w+", "w+b" 或 "wb+"截断或创建以进行更新。
"a+", "a+b", 或 "ab+"追加或创建一个新文件以在 EOF 处进行更新。

如何写入文件

函数描述
$fdisplay类似于 $display,写入文件而不是写入控制台
$fwrite类似于 $write,写入文件而不是写入控制台
$fstrobe类似于 $strobe,写入文件而不是写入控制台
$fmonitor类似于 $monitor,写入文件而不是写入控制台

上述每个系统函数都以基数十进制打印值。 它们还有其他三个版本可以二进制、八进制和十六进制打印值。

函数描述
$fdisplay()默认以十进制打印
$fdisplayb()以二进制打印
$fdisplayo()以八进制打印
$fdisplayh()以十六进制打印

上面的代码给出以下输出,例如

Value displayed with $fdisplay
26
00011010
032
1a
The value displayed with $fwrite
43001010110532b
The value displayed with $fstrobe
60
00111100
074
3c
The value displayed with $fmonitor
60
0
1
2
3
4

读取文件

要从存储器文件中读取和存储数据,我们使用$readmemh$readmemb函数。

$readmemb 任务读取二进制数据,$readmemh 读取十六进制数据。 数据必须存在于文本文件中。 允许使用空格来提高可读性,以及单行和块中的注释。 这些数字必须存储为二进制或十六进制值。 存储器文件的基本形式包含由换行符分隔的数字,这些数字已加载到存储器中。

当不带起始和结束地址调用函数时,它从第一个单元开始将数据加载到存储器中。 必须使用起始和结束地址才能仅将数据加载到存储器的特定部分。

地址可以是显式的,在文件中以 @ 字符给出,后跟一个十六进制地址,数据用空格分隔。 必须记住文件中给出的起始和结束地址范围。 函数调用中的参数必须相互匹配。 否则,将显示一条错误消息,并且加载过程将终止。

读取一行

系统函数$fgets从[hl]fd[/hd]指定的文件中读取字符到变量str中,直到str被填满,或者读取换行符并将其传输到str,或者遇到EOF条件。

如果在读取过程中发生错误,它将返回代码零。 否则,它将返回读取的字符数。

检测EOF

当找到 EOF 时,系统函数$feof 返回一个非零值,否则对于给定的文件描述符作为参数返回零。

fdisplay 的多个参数

当将多个变量提供给$fdisplay时,它只是按给定的顺序一个接一个地打印所有变量,没有空格。

将数据格式化为字符串

$sformat 系统函数中的第一个参数是变量名,结果将放入该变量中。

第二个参数是format_string,它告诉如何将以下参数格式化为字符串。


下一个主题Verilog 全加器