I'm trying to open a file and write stuff, simple. My implementation is not so simple. I'm using Verilog/SystemVerilog and Modelsim on the Windows OS. My command line in Modelsim is:
set generics "-gLOG_FILENAME=log_file?.txt"
vsim -onfinish stop -noglitch -voptargs=+acc -t ns filetest {*}$generics
The question mark is to try and create a file open error.
My Verilog module is
`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
And my file open macro is:
`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);
And finally my sim output:
# 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
is getting a valid MCD (multichannel descriptor), but after the macro checks its validity, the simulator outputs a "Failed to open file" error, and the next attempt to write to that file fails due to unknown file descriptor. If I remove the ? so the filename is valid, it all works. What's going on here? Why do I get a valid MCD when in fact the file did not open?
You are trying to open a file in "append" mode, and apparently it succeeds on your file system. I can open a file with a question mark in its name on my linux OS.
When it can do so, $fopen
returns a non-zero file descriptor.
Refer to IEEE Std 1800-2017, section 21.3.1 Opening and closing files:
The function $fopen opens the file specified as the filename argument and returns either a 32-bit multichannel descriptor or a 32-bit file descriptor, determined by the absence or presence of the type argument.
The file descriptor fd is a 32-bit packed array value. The MSB (bit 31) of a fd is reserved and shall always be set
Since you use the 2-argument form of $fopen
, it returns a file descriptor, which is a number whose MSB is always set. This is why your if (log_handle)
check is true.
Note that the way you call $fopen
, it does not return a multichannel descriptor (MCD).
I tried an experiment where I called $fopen
with a "r" type (open for reading), and the file descriptor was 0.
I don't understand why Modelsim returns a non-zero file descriptor (80000003), but then shows you that warning message. That could be a tool bug. You should contact the vendor.