FileIO - amirrezatav/Verilog_VHDL GitHub Wiki
This is one of the good features that was added to Verilog 2001. In Verilog 1995, file IO was limited to reading hex files into memory array using readmemh and writing file using $display and $monitor.
But in Verilog 2001, following operations can performed.
C or C++ type file operation (like checking end of file).
- Reading charaters from file from a fixed location.
- Reading a formated lines in file.
- Writing a formated lines into file.
Opening a file
A file can be opened for reading or writing, and the syntax is as below.
file = $fopen("filename",r); // For reading
file = $fopen("filename",w); // For writing
Below table shows all the possible $fopen modes.
Closing a file
A file can be cloases as below.
$fclose(file); // Here file is the handle which was assigned with $fopen
Reading data from a file
Verilog 2001 FileIO supports following ways of reading a file.
- Reading a character at a time with $fgetc.
- Reading a line at a time with $fgets.
- Reading formatted data with $fscanf. The $fscanf function reads characters from the file specified by the file descriptor, interprets them according to a format, and stores the results in its arguments.
- Reading binary data with $fread. The $fread function reads binary data from the file specified by the file descriptor into a register or into a memory.
Below example shows how to Verilog fileio in a verification env.
Example : Verilog FileIO
module fileio;
integer in,out,mon;
reg clk;
reg enable;
wire valid;
reg [31:0] din;
reg [31:0] exp;
wire [31:0] dout;
integer statusI,statusO;
dut dut (clk,enable,din,dout,valid);
initial begin
clk = 0;
enable = 0;
din = 0;
exp = 0;
in = $fopen("input.txt","r");
out = $fopen("output.txt","r");
mon = $fopen("monitor.txt","w");
end
always # 1 clk = ~clk;
// DUT input driver code
initial begin
repeat (10) @ (posedge clk);
while ( ! $feof(in)) begin
@ (negedge clk);
enable = 1;
statusI = $fscanf(in,"%h %h\n",din[31:16],din[15:0]);
@ (negedge clk);
enable = 0;
end
repeat (10) @ (posedge clk);
$fclose(in);
$fclose(out);
$fclose(mon);
#100 $finish;
end
// DUT output monitor and compare logic
always @ (posedge clk)
if (valid) begin
$fwrite(mon,"%h %h\n",dout[31:16],dout[15:0]);
statusO = $fscanf(out,"%h %h\n",exp[31:16],exp[15:0]);
if (dout ! == exp) begin
$display("%0dns Error : input and output does not match",$time);
$display(" Got %h",dout);
$display(" Exp %h",exp);
end else begin
$display("%0dns Match : input and output match",$time);
$display(" Got %h",dout);
$display(" Exp %h",exp);
end
end
endmodule
// DUT model
module dut(
input wire clk,enable,
input wire [31:0] din,
output reg [31:0] dout,
output reg valid
);
always @ (posedge clk)
begin
dout <= din + 1;
valid <= enable;
end
endmodule
You could download file compare.v here
Input File
-
0456 08a0
-
0457 08a1
-
0458 08a2
-
0459 08a3
-
045a 08a4
-
045b 08a5
-
045c 08a6
-
045d 08a7
-
045e 08a8
-
045f 08a9
-
0460 08aa
-
0461 08ab
-
0462 08ac
-
0463 08ad
-
0464 08ae
-
0465 08af
-
0466 08b0
-
0467 08b1
-
0468 08b2
-
0469 08b3
-
046a 08b4
-
046b 08b5
-
046c 08b6
-
046d 08b7
-
046e 08b8
-
046f 08b9
-
0470 08ba
-
0471 08bb
-
0472 08bc
-
0473 08bd
-
Expected Output File
-
0456 08a1
-
0457 08a2
-
0458 08a3
-
0459 08a4
-
045a 08a5
-
045b 08a6
-
045c 08a7
-
045d 08a8
-
045e 08a9
-
045f 08aa
-
0460 08ab
-
0461 08ac
-
0462 08ad
-
0463 08ae
-
0464 08af
-
0465 08b0
-
0466 08b1
-
0467 08b2
-
0468 08b3
-
0469 08b4
-
046a 08b5
-
046b 08b6
-
046c 08b7
-
046d 08b8
-
046e 08b9
-
046f 08ba
-
0470 08bb
-
0471 08bc
-
0472 08bd
-
0473 08be