我正在尝试打开一个文件并写入内容,很简单。我的实现没那么简单。 我正在使用 verilog/systemverilog 和 modelsim。我在 modelsim 中的命令行是:
set generics "-gLOG_FILENAME=log_file?.txt"
vsim -onfinish stop -noglitch -voptargs=+acc -t ns filetest {*}$generics
问号是尝试创建文件打开错误。
我的verilog模块是
`include "./simulationDefs.v"
module filetest
#( // Parameter passed in via the vsim command line
parameter LOG_FILENAME
)();
integer log_handle;
initial
begin
$display("log_handle=%h", log_handle); // Print MCD
`log_file_open(LOG_FILENAME, log_handle); // Open File
$display("log_handle=%h", log_handle); // Print MCD again
$fdisplay(log_handle, "Test"); // Try to write to file
end
endmodule
我的文件打开宏是:
`define log_file_open(log_filename, log_handle) \
$display("Attempting to open log file - filename=%s", log_filename); \
log_handle = $fopen(log_filename, "a"); \
if (log_handle) $display("Success, log file opened - log_handle=%h", log_handle); \
else $display("****ERROR LOG FILE NOT OPENED**** filename=%s", log_filename);
最后是我的 sim 输出:
# Start time: 15:24:21 on Oct 10,2023
# Loading sv_std.std
# Loading work.filetest
# log_handle=xxxxxxxx
# Attempting to open log file - filename=log_file?.txt
# Success, log file opened - log_handle=80000003
# log_handle=80000003
# ** Warning: (vsim-3535) [FOFIA] - Failed to open file "log_file?.txt" for appending.
#
# Invalid argument. (errno = EINVAL) : ft.v(18)
# Time: 0 ns Iteration: 0 Instance: /filetest
# ** Error (suppressible): (vsim-PLI-3085) ft.v(18): $fdisplay : Argument 1 is an unknown file descriptor.
# Time: 0 ns Iteration: 0 Instance: /filetest
$fopen 正在获取有效的 MCD,但在宏检查其有效性后,模拟器会输出“无法打开文件”错误,并且由于未知的文件描述符,下次尝试写入该文件会失败。如果我删除 ?所以文件名在所有作品中都是有效的。这里发生了什么?为什么我得到了有效的 MCD,而实际上文件并未打开?
$fopen
返回文件描述符;它并不像您期望的那样表明成功或失败。
请参阅 IEEE Std 1800-2017,第 21.3.1 节 打开和关闭文件:
函数 $fopen 打开指定为文件名参数的文件 并返回 32 位多通道描述符或 32 位文件 描述符,由类型的存在或不存在决定 争论。
文件描述符fd是一个32位压缩数组值。最高有效位(位 31) fd 的值被保留并应始终被设置
由于您使用
$fopen
的 2 参数形式,因此它返回一个文件描述符,这是一个始终设置 MSB 的数字。这就是为什么您的 if (log_handle)
检查始终为真。