Modelsim下$fopen返回有效MCD却无法写入文件的问题咨询
问题描述
我在Windows系统下用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);
仿真输出:
# 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执行$fdisplay时因未知文件描述符报错。移除文件名中的问号后一切正常,请问这个异常的原因是什么?
原因分析
这是Modelsim在Windows平台下的延迟错误报告机制导致的:
$fopen的即时返回逻辑:Windows系统中,$fopen调用时会先预分配一个MCD描述符返回,之后才去执行实际的文件打开操作。你拿到的MCD只是个占位标识,并非真正打开文件后的有效句柄。- 错误滞后触发:文件实际打开失败的错误不会在
$fopen调用时立刻抛出,而是延迟到第一次尝试用这个MCD做读写操作(比如这里的$fdisplay)时才触发警告。但你的宏已经通过if(log_handle)判断“成功”——因为预分配的MCD非零,符合你设定的成功条件。 - Windows文件名规则限制:问号
?是Windows的保留字符,不能用于文件名,这是底层打开失败的根本原因。当文件名合法时,后续实际打开操作顺利完成,MCD会变成有效句柄,所以功能正常。
简单来说:Modelsim先给你一个“占位符”MCD,等你真正要写文件时才发现实际打不开并报错,但你之前已经误以为打开成功了。
内容的提问来源于stack exchange,提问作者Ray H
相关产品推荐
相关产品推荐

