Verilog文件操作
在Verilog仿真中,我们有时需要将仿真得到的数据回写到文件中去,在Verilog语法中提供$fdisplay, $fwrite, $fstrobe, $fmonitor等系统函数来帮助开发者将数据写回到文件中。
1. $display() 函数的使用
语法解析:
$fdisplay(<file_desc>,"string",variables);
// file_desc : 文件句柄,表示要对哪个文件进行写操作
// string : 写入文件的格式
// variables : 写入的数值
$fdisplay()的使用方法和$display()系统函数的使用方法很类似,$display()是将格式化的结构输出到控制台上,而$fdisplay()是将格式化的输出结果写入到文件中。
例1:打开一个文件并写入相关的数据
`timescale 1ns/1ps
module sim_top();
localparam FILE_NAME = "../../../led_sim.txt";
integer file_handle = 0;
initial begin
file_handle = $fopen(FILE_NAME,"w");
if(!file_handle) begin
$dispaly("Could not open file \r ");
$stop;
end
$fdisplay(file_handle, "new data1: %h", file_handle);
$fdisplay(file_handle, "new data2: %h", 16'h1234);
$fdisplay(file_handle, "new data3: %d", 123);
$fclose(file_handle);
#200, $stop;
end
endmodule
$fopen()用来打开操作系统上的文件,$fdisplay()将数据格式化地写入到文件中去。$fclose()用于将打开的文件关闭。由于打开的文件为文本格式的,所以存储的文件也可以被文本工具打开。
"led_sim.txt"的文件内容如下所示:
new data1: ffffb1e0
new data2: 1234
new data3: 123
2. $fwrite()函数的使用
语法解析:
$fwrite(<file_desc>,"string",variables);
// file_desc : 文件句柄,表示要对哪个文件进行写操作
// string : 写入文件的格式
// variables : 写入的内容
$fwrite()的使用方法和$write()系统函数的使用也是很类似的。$fwrite()和$fdisplay()功能一样,但是没有自动换行功能。
例2:
`timescale 1ns/1ps
module sim_top();
localparam FILE_NAME = "../../../led_sim.txt";
integer file_handle = 0;
initial begin
file_handle = $fopen(FILE_NAME,"w");
if(!file_handle) begin
$dispaly("Could not open file \r ");
$stop;
end
$fwrite(file_handle, "new data1: %h", file_handle);
$fwrite(file_handle, "new data2: %h", 16'h1234);
$fwrite(file_handle, "new data3: %d", 123);
$fclose(file_handle);
#200, $stop;
end
endmodule
"led_sim.txt"的文件内容如下所示:
new data1: ffffb1e0 new data2: 1234 new data3: 123
3. $fstrobe()函数的使用
语法解析:
$fstrobe(<file_desc>,"string",variables);
// file_desc : 文件句柄,表示要对哪个文件进行写操作
// string : 输出文件的格式,参考$display()的格式用法
// variables : 准备写入的变量
$fstrobe()的使用方法和$strobe()系统函数的使用也是很类似的,都是在时间节点到达时,执行函数。
例3:
`timescale 1ns/1ps
module sim_top();
wire [3:0] y;
reg [2:0] a = 1, b = 2;
assign y = a + b;
localparam FILE_NAME = "../../../led_sim.txt";
integer file_handle = 0;
initial begin
file_handle = $fopen(FILE_NAME,"w");
if(!file_handle) begin
$dispaly("Could not open file \r ");
$stop;
end
$fstrobe(file_handle, "%h", $time);
$fstrobe(file_handle, "%h", 16'h5678);
$fstrobe(file_handle, "%h", y);
a = 5;
$fstrobefile_handle, "%h", y);
#10
a = 9;
$fstrobefile_handle, "%c", y);
$fclose(file_handle);
#200, $stop;
end
endmodule
"led_sim.txt"的文件内容如下所示:
00000000000000000000
5678
7
7
$fstrobe()被调用的时刻所有语句都执行完才开始打印。上面的代码被"#10"分割为两个执行时刻,"#10"之前所有语句执行完毕后"a=5"已经生效了,因此两次打印的y的值都是7。而"#10"之后所有语句执行完毕时文件已经被关闭了,所以a=9没有打印出来。
4.$fmonitor()函数的使用
语法解析:
$fmonitor(<file_desc>,"string",variables);
// file_desc : 文件句柄,表示要对哪个文件进行写操作
// string : 输出文件的格式,参考$display()的格式用法
// variables : 写入的数据
$fmonitor()和$monitor()系统函数的使用类似,只要参数列表中的variable发生变化,并且到了执行时刻其他语句都执行完毕,它就会执行。优点是,不必纠结在哪里打印输出,只要触发条件,就可以自动打印输出。
例4:
`timescale 1ns/1ps
module sim_top();
wire [3:0] y;
reg [2:0] a = 1, b = 2;
assign y = a + b;
localparam FILE_NAME = "../../../led_sim.txt";
integer file_handle = 0;
initial begin
file_handle = $fopen(FILE_NAME,"w");
if(!file_handle) begin
$dispaly("Could not open file \r ");
$stop;
end
$fmonitor(file_handle, "%h", $time);
$fmonitor(file_handle, "%h", 16'h5678);
$fmonitor(file_handle, "%h", y);
a = 5;
#10
a = 3;
#10
a = 4;
$fclose(file_handle);
#200, $stop;
end
endmodule
"led_sim.txt"的文件内容如下所示:
00000000000000000000
5678
7
5
我们可以看到,$fmonitor()可以监控数据的变化,不需要每次都调用$fmonitor()。注意,上面的代码中的两个"#10"将执行过程分成了三个阶段,第一个阶段所有代码执行完毕时,"a=5"所以y打印出来是7,第二个阶段"a=3"所以y打印出来是5,第三个阶段所有代码执行完毕文件关闭了,所以a=4没有打印出来。

浙公网安备 33010602011771号