Issue #21
$fopen() & friends don't work as expected...
| Status: | Closed | Start date: | 07/14/2008 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | Wilson Snyder | % Done: | 0% |
|
| Category: | WrongRuntimeResult | |||
| Target version: | - |
Description
file test.vt:
module testbench;
integer infile, outfile, count, a;
initial begin
infile = $fopen("test.in", "r");
outfile = $fopen("test.out", "w");
$display("count == %d, infile %d, outfile %d", count, infile, outfile);
count = $fscanf(infile, "%d\n", a);
$display("count == %d, infile %d, outfile %d", count, infile, outfile);
$fwrite(outfile, "# a\n");
$fwrite(outfile, "%d\n", a);
$fclose(infile);
$fclose(outfile);
$finish;
end
endmodule
file test.in:
1 2 3Icarus Verilog output:
./test.vvp count == x, infile -2147483645, outfile -2147483644 count == 1, infile -2147483645, outfile -2147483644test.out generated when simulating using Icarus Verilog:
# a
1
Verilator creates empty output file and this command line output:
./test.verilated count == 0, infile 0, outfile 0 count == 0, infile 0, outfile 0
History
Updated by Wilson Snyder almost 5 years ago
- Category set to WrongRuntimeResult
- Status changed from New to AskedReporter
- Assignee set to Wilson Snyder
Works for me. Perhaps try
`verilator_file_descriptor infile, outfile;
instead of a integer.
Updated by Holger Wächtler almost 5 years ago
mmh,... why verilator_file_descriptor, why should this be verilator-specific? Using `verilator_file_descriptor yields:
%Error: test.vt:2: Define or directive not defined: `verilator_file_descriptor %Error: test.vt:2: syntax error, unexpected ',', expecting IDENTIFIER %Error: Cannot continue %Error: Command Failed verilator_bin --cc test.vt -Mdir .verilator_obj_dir/test --prefix simulation --exe verilator_main.cpp make: *** [test.verilated] Error 10
Updated by Holger Wächtler almost 5 years ago
btw, I forgot to submit verilator_main.cpp:
#include "simulation.h"
#include "verilated.h"
int main (int argc, char **argv, char **env)
{
simulation *sim = new simulation;
while (!Verilated::gotFinish())
sim->eval();
exit(0);
}
Updated by Wilson Snyder almost 5 years ago
You also need `include "verilated.h"
Verilator doesn't use MCD instead C file descriptors which in C under -m64 are 64 bits. See the docs.
This may not be the problem though...
Updated by Holger Wächtler almost 5 years ago
mh, this would render the principal idea of using fwrite & friends for portable testcases ridiculous: if one has to touch&modify every testcase for verilator, then one could as well directly use C wrappers instead:
`define fopen(x) $c(...) etc...
Isn't a proper MCD implementation very straightforward? (e.g. maintain an array of refcounted open file descriptors/file name pairs, and verilog-MCDs could be simple indices into this array? Entries are only valid if refcount > 0, fopen increases refcount for already open file name, fclose decrements it).
Or do I miss something that would make this non-trivial?
Updated by Wilson Snyder almost 5 years ago
There are some implementation issues, but the main issue is I consider Verilator a synthesis subset simulator, and have no time to deal with Verilogisms (MCD) that simply obscure a nice C equivelent. However if you want to implement it, I'd accept it.
To the main issue, does that fix it nor not?
Updated by Holger Wächtler almost 5 years ago
yes, it works, just... as said before. I'll take a look into the MCD issue next days... will you leave the ticket open, or shall I open a new one?
Updated by Wilson Snyder almost 5 years ago
- Status changed from AskedReporter to Closed
There is still a fix here... I updated HEAD to warn if the $fopen etc descriptor isn't 64 bits so these errors can be caught.
For MCD support please file another bug, thanks.
Updated by Holger Wächtler almost 5 years ago
I took a closer look on the Icarus mcd implementation.
verilog/vvp/vpi_mcd.cc is pretty self-containing, applying these changes makes it compile stand-alone:typedef unsigned int PLI_UINT32; typedef signed int PLI_INT32; //# include "vpi_priv.h"
It defines the following functions, which can be used instead of libc's fopen/fprintf/fclose/fflush:
extern "C" PLI_UINT32 vpi_mcd_close(PLI_UINT32 mcd) extern "C" char *vpi_mcd_name(PLI_UINT32 mcd) extern "C" PLI_UINT32 vpi_mcd_open(char *name) extern "C" PLI_INT32 extern "C" PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...) extern "C" PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) extern "C" PLI_INT32 vpi_fopen(const char*name, const char*mode) extern "C" FILE *vpi_get_file(PLI_INT32 fd)
Replacing the direct libc calls with vpi_mcd_*() should be sufficient -- and as side-effect a first minimal basis for the VPI core comes in for free. The file is GPL'd, so there should be no licensing issue.
Also available in: Atom
![[logo]](/img/veripool_small.png)