SystemVerilog读取文件的一个有趣现象(feof多读一次的问题)
在学习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中的软件编程思想。
为自己加油,扎实自己的基础,总有厚积薄发的时候。