Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$fopen() & friends don't work as expected... #21

Closed
veripoolbot opened this issue Jul 14, 2008 · 9 comments
Closed

$fopen() & friends don't work as expected... #21

veripoolbot opened this issue Jul 14, 2008 · 9 comments
Assignees
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed

Comments

@veripoolbot
Copy link
Contributor


Author Name: Holger Wächtler
Original Redmine Issue: 21 from https://www.veripool.org
Original Date: 2008-07-14
Original Assignee: Wilson Snyder (@wsnyder)


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
3

Icarus Verilog output:

./test.vvp
count ==           x, infile -2147483645, outfile -2147483644
count ==           1, infile -2147483645, outfile -2147483644

test.out generated when simulating using Icarus Verilog:

1. 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

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2008-07-14T18:03:55Z


Works for me. Perhaps try

`verilator_file_descriptor infile, outfile;

instead of a integer.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Holger Wächtler
Original Date: 2008-07-14T19:10:41Z


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

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Holger Wächtler
Original Date: 2008-07-14T19:11:51Z


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);
}


@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2008-07-14T20:04:37Z


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...

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Holger Wächtler
Original Date: 2008-07-14T20:27:13Z


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?

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2008-07-14T20:43:13Z


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?

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Holger Wächtler
Original Date: 2008-07-14T20:51:57Z


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?

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2008-07-14T21:16:37Z


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.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Holger Wächtler
Original Date: 2008-07-15T10:27:30Z


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.

@veripoolbot veripoolbot added area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed labels Dec 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed
Projects
None yet
Development

No branches or pull requests

2 participants