Overview
The verilog spec is a bit vague on the details of file i/o system tasks. According to the grammar, they're statements. But according to their description, they can be invoked as statements or used as expressions which return values.
The way we've opted to handle this up until now is a bit ad-hoc. We've chosen to treat everything other than $fopen and$feof as statements. $feof we've chosen to treat as an expression, and $fopen we've hacked in a weird way where it can only appear on the right hand side of a declaration.
This was good for getting file i/o off the ground, but we can do better. The right thing to do is to add two different versions of tasks which can be used as statements or expressions to the grammar: one to represent a statement, and one to represent an expression.
If we do this well, we should be able to support the following code, which it should go without saying, we fall over and die on currently.
reg[31:0] r = 0;
integer fd = $fopen("path/to/file.dat");
wire eof = $feof(fd);
always @(posedge clock.val) begin
if (eof) begin
fd = $fopen("path/to/some_other_file.dat");
end else begin
$fread(fd, r);
end
end
Deliverables