SystemVerilog读取文件的一个有趣现象(feof多读一次的问题)

发布时间 2023-06-20 22:03:36作者: 颜秋哥

         在学习SystemVerilog读取文件时,练习读取自身的代码,代码如下:

 1 module Test;
 2     int file;
 3 
 4     initial
 5     begin
 6         string s;
 7         file = $fopen("TestFile.sv", "r");
 8         while(!$feof(file))
 9         begin
10             //s = "";
11             $fscanf(file, "%s", s);
12             $display("%s",s);
13         end
14         $fclose(file);
15     end
16 endmodule

         注意注释掉的代码,如果不在循环开始的时候,设置s为空字符串,在ModelSim中仿真结果会多输出一行#endmodule,仿真结果如下:

         如果在循环开始时,设置s="",则最后会多输出一行空白字符。也就是说循环多执行了一次,作为对比,使用C语言再重复一次上述代码。为了与Verilog代码能对应,C代码的风格不是很好,但更容易理解:

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     char   s[128];//字符串都比较短,所以这里使用定长数组简化代码
 6     FILE* file = fopen("TestFile.sv", "r");
 7     while(!feof(file))
 8     {
 9         fscanf(file, "%s", s);
10         printf("%s\n",s);
11     }
12     fclose(file);
13     return 0;
14 }

          gcc编译运行结果如下:

         注意,在最后一行,同样是多输出了一次endmodule。也就是说SystemVerilog和C语言的运行结果是一样的,也就是同样存在feof多读一次的问题。所以,《SystemVerilog验证测试平台编写指南》中的例子,使用$feof判断文件结束,也同样会多循环一次。

        将代码修改一下,如下所示:

 1 module Test;
 2     int file;
 3 
 4     initial
 5     begin
 6         string s;
 7         file = $fopen("TestFile.sv", "r");
 8         $fscanf(file, "%s", s);
 9         while($feof(file) == 0)
10         begin
11             //s = "";
12             $display("%s",s);
13             $fscanf(file, "%s", s);
14         end
15         $fclose(file);
16     end
17 endmodule

            这样,再次进行仿真,就不会出现多读一次的情况了。这个方案就是C语言的修改方案,用在SystemVerilog里也是可以的,因为这些函数的行为是一样的。在浏览器中搜索“feof函数多读一次”的关键字,就可以找到对应的解决办法。

           具备数字电路基础,就能够理解硬件描述语言的“硬件描述”的含义,理解硬件的并行运行思想;具备C/C++编程基础,那么就很容易理解SystemVerilog中的软件编程思想。

           为自己加油,扎实自己的基础,总有厚积薄发的时候。