掌握 Verilog 文件 I/O:打开、读取、写入和关闭
Verilog 提供了系统任务和函数,用于打开文件、向文件输出值、从文件读取值并加载到变量中,以及关闭文件。
打开和关闭文件
module tb;
// 声明一个变量存储文件句柄
integer fd;
initial begin
// 以“写”权限打开名为 "my_file.txt" 的新文件
// 并将文件句柄指针存储在变量 "fd" 中
fd = $fopen("my_file.txt", "w");
// 关闭由 "fd" 指向的文件句柄
$fclose(fd);
end
endmodule
文件打开模式
| 参数 | 描述 |
|---|---|
| "r" 或 "rb" | 以读取方式打开 |
| "w" 或 "wb" | 创建新文件用于写入。若文件存在,则截断为零长度并覆盖 |
| "a" 或 "ab" | 若文件存在,则追加(在文件末尾打开写入),否则创建新文件 |
| "r+", "r+b" 或 "rb+" | 以读写方式打开 |
| "w+", "w+b" 或 "wb+" | 截断或创建用于更新 |
| "a+", "a+b" 或 "ab+" | 追加,或在文件末尾创建新文件用于更新 |
如何写入文件
| 函数 | 描述 |
|---|---|
| $fdisplay | 类似 $display,但将输出写入文件 |
| $fwrite | 类似 $write,但将输出写入文件 |
| $fstrobe | 类似 $strobe,但将输出写入文件 |
| $fmonitor | 类似 $monitor,但将输出写入文件 |
上述系统函数默认以十进制打印值。它们还有三个变体分别用于二进制、八进制和十六进制打印。
| 函数 | 描述 |
|---|---|
| $fdisplay() | 默认以十进制打印 |
| $fdisplayb() | 以二进制打印 |
| $fdisplayo() | 以八进制打印 |
| $fdisplayh() | 以十六进制打印 |
module tb;
integer fd;
integer i;
reg [7:0] my_var;
initial begin
// 创建新文件
fd = $fopen("my_file.txt", "w");
my_var = 0;
$fdisplay(fd, "Value displayed with $fdisplay");
#10 my_var = 8'h1A;
$fdisplay(fd, my_var); // 十进制显示
$fdisplayb(fd, my_var); // 二进制显示
$fdisplayo(fd, my_var); // 八进制显示
$fdisplayh(fd, my_var); // 十六进制显示
// $fwrite 不会自动在每行末尾打印换行符 '\n'
// 因此下面的值将出现在同一行
$fdisplay(fd, "Value displayed with $fwrite");
#10 my_var = 8'h2B;
$fwrite(fd, my_var);
$fwriteb(fd, my_var);
$fwriteo(fd, my_var);
$fwriteh(fd, my_var);
// 使用 '\n' 跳到新行,并用 strobe 打印非阻塞赋值后的最终值
$fdisplay(fd, " Value displayed with $fstrobe");
#10 my_var <= 8'h3C;
$fstrobe(fd, my_var);
$fstrobeb(fd, my_var);
$fstrobeo(fd, my_var);
$fstrobeh(fd, my_var);
#10 $fdisplay(fd, "Value displayed with $fmonitor");
$fmonitor(fd, my_var);
for(i = 0; i < 5; i= i+1) begin
#5 my_var <= i;
end
#10 $fclose(fd);
end
endmodule
仿真日志
Value displayed with $fdisplay 26 00011010 032 1a Value displayed with $fwrite 43001010110532b Value displayed with $fstrobe 60 00111100 074 3c Value displayed with $fmonitor 60 0 1 2 3 4
如何读取文件
读取一行
系统函数 $fgets 从 [hl]fd[/hd] 指定的文件中读取字符到变量 str,直到 str 填满、读取到换行符并传送给 str、或遇到 EOF 条件。
若读取过程中发生错误,返回码为零;否则返回读取的字符数。
检测 EOF
系统函数 $feof 在发现 EOF 时返回非零值,否则针对给定的文件描述符返回零。
module tb;
reg[8*45:1] str;
integer fd;
initial begin
fd = $fopen("my_file.txt", "r");
// 循环读取直到 EOF
while (! $feof(fd)) begin
// 将当前行读入变量 'str'
$fgets(str, fd);
// 显示变量内容
$display("%0s", str);
end
$fclose(fd);
end
endmodule
$fdisplay 多参数用法
当给 $fdisplay 传递多个变量时,它会按给定顺序依次打印所有变量,之间不加空格。
module tb;
reg [3:0] a, b, c, d;
reg [8*30:0] str;
integer fd;
initial begin
a = 4'ha;
b = 4'hb;
c = 4'hc;
d = 4'hd;
fd = $fopen("my_file.txt", "w");
$fdisplay(fd, a, b, c, d);
$fclose(fd);
end
endmodule
仿真日志
10111213
将数据格式化为字符串
$sformat 系统函数的第一个参数是存放结果的变量名。第二个参数是 format_string,指定后续参数如何格式化为字符串。
module tb;
reg [8*19:0] str;
reg [3:0] a, b;
initial begin
a = 4'hA;
b = 4'hB;
// 将 'a' 和 'b' 按格式化字符串格式化并存入 'str'
$sformat(str, "a=%0d b=0x%0h", a, b);
$display("%0s", str);
end
endmodule
仿真日志
xcelium> run a=10 b=0xb xmsim: *W,RNQUIE: Simulation is complete.
Verilog
- Verilog基础:设计你的第一个与门
- Verilog 入门:数字电路设计完整教程
- 掌握 Verilog 拼接操作:实用指南
- 深入理解 Verilog 赋值语句:类型、语法与最佳实践
- Verilog阻塞与非阻塞赋值:关键区别详解
- 掌握Verilog函数:高效RTL设计的复用利器
- 理解Verilog任务:函数vs任务、语法与用法全解析
- Verilog 时钟发生器设计与实现指南
- 掌握 Verilog 数学函数:高效硬件设计的利器
- 掌握 Verilog $timeformat:精度控制与显示格式化
- 理解与打印 Verilog 任意作用域下的 Timescale
- Verilog 入门指南:Hello World 示例