• Verilog的系统任务----$fopen、$fclose和$fdisplay, $fwrite,$fstrobe,$fmonitor


    文章目录

            概述

            $fopen

            $fdisplay, $fwrite,$fstrobe,$fmonitor

            $fclose

            仿真测试

            总结与参考


    概述

            在这篇文章(Verilog的系统任务----$readmemh和$readmemb)中,介绍了Verilog的系统任务$readmemh和$readmemb的用法,利用这两个系统任务,可以实现从文件中读取数据到仿真中数组的功能。

            无独有偶,有时候在仿真时,我们同样需要将获取的数据写入文件中,以便后续的分析和利用。下面这三类系统任务可以用来实现对文件的写入操作:

    • $fopen:打开指定文件
    • $fclose:关闭指定文件
    • $fdisplay, $fwrite,$fstrobe,$fmonitor:对指定文件进行特定的写入操作

    $fopen

            系统任务$fopen可以用来打开指定的文件(以便后续对其进行写入操作),其返回值为integer变量,表示当前文件的句柄值,获取句柄值后,后续就可以根据句柄值对不同的文件进行写入操作。即

    integer        handle1;                                 //定义句柄1

    handle1 = $fopen("file_name",type)       //以指定类型(type)的方式来打开文件,并将其返回值赋给handle1

            type指定了打开文件的类型,可以是以下种类:

            通常情况下,我们使用 w 来作为类型值,即以对一个ASCII文本文件进行写操作的方式来打开该文件 (txt)。

            比如,我们在如下路径新建一个TXT文件file_test1.txt:

            然后就可以用下述的方法将其打开:

    integer        handle1;                                                           //定义句柄1

    handle1 = $fopen("D:/file_test/file_test1.txt","w");          //以w类型(写)的方式来打开文件,并将其返回值赋给handle1


    $fdisplay, $fwrite,$fstrobe,$fmonitor

            这4个函数都可以对指定文件进行打印或写入操作,其用法与对应的$display, $write,$strobe,$monitor几乎一致。建议参考:Verilog中的系统任务(显示/打印类)--$display, $write,$strobe,$monitor_孤独的单刀的博客-CSDN博客_verilog打印Verilog中的系统任务(显示/打印类)--$display, $write,$strobe,$monitorhttps://wuzhikai.blog.csdn.net/article/details/125340502        区别在于$display等函数是直接在仿真中进行打印,而$fdisplay等函数是对指定文件进行打印,需要通过句柄来指定是对具体哪个文件进行操作。如:

    //指定句柄并打开文件

            reg                data;

            integer        handle1;                                                         //定义句柄1

            handle1 = $fopen("D:/file_test/file_test1.txt","w");       //以w类型(写)的方式来打开文件,并将其返回值赋给handle1

    //对指定文件写入数据

            $fdisplay(handle1,"%d\n",data);                                    //按照十进制格式写入数据到handle1对应的文件中,只能逐个写入


    $fclose

            $fclose系统任务用来关闭指定文件,关闭后即无法对该文件进行操作。其格式如下:

    $fclose(handle1);        //关闭文件file_test1,至此文件操作结束


    仿真测试

            首先新建两个TXT文件来后续对其写入数据,其名称和路径如下:

             

            然后,编写一个testbench实现以下功能:

    • 构建计数器1:从0000-1111循环计数;将0000开始的10个值写入文件file_test1.txt,然后关闭文件写入功能
    • 构建计数器2:从1111-0000循环计数;将1111开始的10个值写入文件file_test2.txt,然后关闭文件写入功能
    1. `timescale 1ns / 1ns
    2. module file_test();
    3. reg [3:0] cnt1; //计数器1
    4. reg [3:0] cnt2; //计数器2
    5. reg clk; //主时钟
    6. reg rst_n; //复位
    7. integer handle1; //定义文件1句柄
    8. integer handle2; //定义文件2句柄
    9. //初始化赋值
    10. initial begin
    11. clk <= 1'b0;
    12. rst_n <= 1'b0;
    13. #20
    14. rst_n <= 1'b1;
    15. #200
    16. $finish;
    17. end
    18. //打开文件1、文件2
    19. initial begin
    20. handle1 = $fopen("D:/file_test/file_test1.txt","w");
    21. handle2 = $fopen("D:/file_test/file_test2.txt","w");
    22. end
    23. //计数器1从0000-1111循环计数
    24. always @(posedge clk or negedge rst_n) begin
    25. if(rst_n == 1'b0)
    26. cnt1 <= 4'b0000;
    27. else
    28. cnt1 <= cnt1 + 1'b1;
    29. end
    30. //计数器2从1111-0000循环计数
    31. always @(posedge clk or negedge rst_n) begin
    32. if(rst_n == 1'b0)
    33. cnt2 <= 4'b1111;
    34. else
    35. cnt2 <= cnt2 - 1'b1;
    36. end
    37. //将计数器1的10个值打印到文件1
    38. always @(posedge clk or negedge rst_n) begin
    39. if(rst_n == 1'b0)
    40. ;
    41. else if(cnt1 >4'd9)
    42. $fclose(handle1);
    43. else
    44. $fdisplay(handle1,"%d",cnt1); //以10进制的方式将当前的cnt1的值写入文件1
    45. end
    46. //将计数器2的10个值打印到文件2
    47. always @(posedge clk or negedge rst_n) begin
    48. if(rst_n == 1'b0)
    49. ;
    50. else if(cnt2 <4'd6)
    51. $fclose(handle2);
    52. else
    53. $fdisplay(handle2,"%d",cnt2); //以10进制的方式将当前的cnt2的值写入文件2
    54. end
    55. always #10 clk = ~clk; //主时钟20ns
    56. endmodule

            使用vivado自带仿真器进行仿真,仿真结束后,打开两个文本文件,观察其写入数据是否与预期一致。

            文件1:依次写入0-9共10个数据

            文件2:依次写入15-6共10个数据 

     

            对两个文件的数据写入均与预期设计一致。


    总结与参考

    • 系统任务$fopen用来打开指定的文件,后续才可以对文件进行操作
    • 系统任务$fclose用来关闭指定的文件,结束对文件的操作
    • 系统任务$fdisplay, $fwrite,$fstrobe,$fmonitor可以用来对文件写入数据、打印文本,其用法基本与对应的系统任务$display, $write,$strobe,$monitor一致,只不过要加上表示对应文件的句柄值

            参考资料1:IEEE Standard for Verilog® Hardware Description Language(IEEE Std 1364™-2005)


    • 📣博客主页:wuzhikai.blog.csdn.net
    • 📣本文由 孤独的单刀 原创,首发于CSDN平台🐵
    • 📣您有任何问题,都可以在评论区和我交流📞!
    • 📣创作不易,您的支持是我持续更新的最大动力!如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

  • 相关阅读:
    深入理解并发编程同步工具类
    线程池的实现
    PCB layout有DRC为什么还要用CAM和DFM检查?
    HostMonitor邮件告警详细解读----生产可用
    【Tomcat】为Tomcat服务配置本地Apr库以提升性能
    软件工程计算机操作系统
    uniapp中videojs、renderjs的使用
    Java · 逻辑控制(顺序结构 · 分支结构 · 循环结构) · 输入输出语句
    [机器学习笔记]K-means聚类——进行广告效果分析
    从零开始学数据结构系列之第四章《 最小生成树概念》
  • 原文地址:https://blog.csdn.net/wuzhikaidetb/article/details/126006403