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,
$fopenreturns a non-zero file descriptor.Refer to IEEE Std 1800-2017, section 21.3.1 Opening and closing files:
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 yourif (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
$fopenwith 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.