在Verilog 仿真工程中,有时我们需要从操作系统上得到相关的数据,有时需要将仿真数据保存到操作系统中,对于台式机可以读取或存储数据到本地硬盘。由于操作系统上的数据都是以文件方式保存的,这就需要利用Verilog 仿真系统函数来完成相应的操作。本文我们主要讨论Verilog 仿真文件操作中的打开,关闭操作函数$fopen,$fclose,$ferror等。 关于Verilog 仿真中的文件操作,只能在仿真中使用, 不能用于FPGA 的综合,因此一般用于testbench文件中。
1. $fopen函数:
$fopen的语法格式如下:
integer <file_desc>; //声明 integer 变量,用于存储文件打开后返回的整数值,用于操作文件的句柄。 <file_desc> = $fopen("<file_name>", "<file_mode>");
- file_desc :文件的句柄,反映文件打开是否成功, 如果file_des == 0, 文件打开失败; 如果file_des != 0, 文件打开成功。
- file_name :在操作系统中的文件名称。
- file_mode : 指示以什么样的方式打开操作系统中的文件。
file_mode 列表:
file_mode | 描述 |
r | 打开ASCII文本文件(文件必须存在,而且只能读文件内容), r–>read text |
rb | 打开Binary 二进制文件(文件必须存在, 而且只能读文件内容),rb–> read binary |
w | 创建一个新的ASCII文本文件,做写操作;如果这个文件已经存在,删除这个文件中的内容,再做写操作, w–>write text |
wb | 创建一个新的Binary 二进制文件,做写操作;如果这个文件已经存在,删除这个文件中的内容,再做写操作, wb–> write binary |
a | 创建一个新的ASCII文本文件,做写操作;如果这个文件已经存在,写操作的内容添加在文件原本的内容之后, a–>append, |
ab | 创建一个新的Binary 二进制文件,做写操作;如果这个文件已经存在,写操作的内容添加在文件原本的内容之后, a–>append binary |
r+ | 打开ASCII文本文件(可以对文件进行读写操作) r+–> read and write |
例1:在当前目录下以只读的方式打开test.txt, 判别该文件是否成功打开。
initial begin fd = $fopen("test.txt", "r"); if(fd == 0) begin $display ("Could not open the File !"); $stop; end $display ("open the File successfully !"); $stop; end
例1 程序解释如下:
- 定义文件句柄 fd;
- 打开文件test.txt,以文本方式只读打开;打开的test.txt 必须在仿真工程的缺省目录(以test_file工程举例,仿真工程默认路径为…\file_test\file_test.sim\sim_1\behav\xsim)中。
- 如果文件打开失败,显示输出错误信息。
在打开文件时,可以指定绝对路径,或相对路径打开指定的文件。如例2所示,
例2:指定文件路径,并打开文件。
integer fd; initial begin fd = $fopen("c:/my_prj/test.txt", "r"); if(fd == 0) begin $display ("Could not open the File !"); $stop; end $display ("open the File successfully !"); $stop; end
以文本方式打开c 盘下,my_prj 目录中的test.txt文件。这样就可以重定向文件的位置,注意,这里使用的是’/‘ 而不是’\‘ 来定位文件。一般情况下, 打开文件时,需要检查打开的文件句柄,以确定文件是否打开成功。
2. $fclose函数
$fclose 关闭已经打开的文件。
$fclose的语法格式如下:
$fclose(<file_desc>);
file_desc 为文件句柄, 这个句柄为之前使用$fopen 系统函数所打开的文件句柄。
例3:利用相对路径打开和关闭文件。
`timescale 1ns / 1ps module sim_tb(); localparam FILE_NAME = "../../../led_sim.sim"; integer file_handle = 0; initial begin file_handle = $fopen(FILE_NAME,"r"); $display("file_handle = %d ",file_handle); if(!file_handle) begin $display("Could not open File !\r"); $stop; end else $fclose(file_handle); $display("File has been closed ! \r"); $stop; end endmodule
上例首先使用$fopen 打开文件; 文件使用结束后, 使用$fclose 关闭文件。注意一定要使用对应的文件句柄,如本例中使用的句柄为 file_handle。
在仿真中也可以同时打开多个文件。多文件打开及操作方式如例4所示。
例4:
`timescale 1ns / 1ps module sim_top(); integer fd0 = 0; integer fd1 = 0; localparam FILE_NAME = "../../../led_sim.sim"; initial begin fd0 = $fopen(FILE_NAME,"r"); $display("fd0 = %d ",fd0); if(!fd0) begin $display("Could not open fd0 file \r"); $stop; end fd1 = $fopen("test.txt", "r"); if(fd1 == 0) begin $display("Could not open fd1 file"); $stop; end $fclose(fd0); $display("led_sim.sim has been closed !"); $fclose(fd1); $display("test.txt has been closed !"); $stop; end endmodule
在仿真中, 可以打开很多文件, 在各个文件的使用后, 可以根据需要的顺序关闭,不一定按照打开文件的顺序执行。
注意:
Verilog‐1995中在文件的输入/输出操作方面功能非常有限,并且规定同时打开的I/O文件数不能多于31个。
Verilog‐2001增加了新的系统任务和函数,并且规定同时打开的文件数目为230个。
老师好,例1,相对路径,仿真时显示No such file or directory. (errno = ENOENT) : ../../../../timing2.srcs/sim_1/new/fopen.v(30)
您可以仿真试试一下
这个文件需要自己创建,如果没有这个文件,或者找不到这个文件,就会打印错误信息。 同时在console中可以看到 “Could not open the File !”
test.txt 文件必须放在 proj_name.sim/sim_1/behav/xsim 这个目录下, 其中 proj_name 为你的工程名字