【FPGA/verilog -入门学习11】verilogTestbench中的文本文件写入,读出,打印等操作

这篇具有很好参考价值的文章主要介绍了【FPGA/verilog -入门学习11】verilogTestbench中的文本文件写入,读出,打印等操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文参考:Verilog中的系统任务(显示/打印类)--$display, $write,$strobe,$monitor-CSDN博客

Verilog:parameter、localparam的区别和用法-CSDN博客

Verilog的系统任务----$fopen、$fclose和$fdisplay, $fwrite,$fstrobe,$fmonitor_verilog fopen-CSDN博客

Verilog的系统任务----$readmemh和$readmemb-CSDN博客

1,$display

$display可以直接打印一条文本信息,并在每一次$display执行后会自动换行,比如:

`timescale 1ns/1ns
module test_tb();
 
initial begin
    $display("China NO1!");
    $display("USA NO2!");
end

verilog fwrite连续打印,verilog &FPGA,fpga开发,学习

2,$write

$write的用法与$display一致,区别在于,一条$write语句执行完后,不会自动换行。比如下面的代码:

 
`timescale 1ns/1ns
module test_tb();
 
initial begin
    $write("China NO1!");
    $write("USA NO2!");
end

verilog fwrite连续打印,verilog &FPGA,fpga开发,学习

这两个系统函数除了直接打印文本外,也可以打印变量的值,其格式为(以$display为例):

$display("%b %b",a,b) ;

verilog fwrite连续打印,verilog &FPGA,fpga开发,学习

3,$strobe

$strobe 为选通显示任务。$strobe 使用方法与 $display 一致,但打印信息的时间和 $display 有所差异(也可以直接打印文本)。

当许多语句与 $display 任务在同一时间内执行时,这些语句和 $display 的执行顺序是不确定的,一般按照程序的顺序结构执行。

两者的区别在于:$strobe命令会在当前时间部结束时完成;

而$display是只要仿真器看到就会立即执行。

$strobe 是在其他语句执行完毕之后,才执行显示任务。例如:

 `timescale 1ns/1ns
module test_tb();
 
reg [3:0]  a ;
initial begin
    $strobe("begin!");
    a = 1 ;
    #1 ;
    a <= a + 1 ;
    //第一次显示
    $display("$display excuting result: %d.", a);
    $strobe("$strobe excuting result: %d.", a);
    #1 ;
    $display();
    //第二次显示
    $display("$display excuting result: %d.", a);
    $strobe("$strobe excuting result: %d.", a);
    $strobe("end!");
end
endmodule 

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

总结:$display() 和他前面一条语句同时执行,没有延时,

而 $strobe 会等待上一条指令执行完成后输出

可以看到,$strobe与$display的打印内容不是一致的。

这是因为该语句: a <= a + 1 ;也就是说a的第二次赋值是非阻塞赋值,而非阻塞赋值是需要时间的。

在第一次打印时,$display不会管你a是阻塞赋值还是非阻塞赋值,它就直接打印a当前的值1。而$strobe则会等到非阻塞赋值完成后再打印,所以其打印的值为2。

在第二次打印时,又延时了1ns,所以此时的非阻塞赋值完成,那么$strobe与$display的打印内容就均为2了。

所以$strobe这个系统任务通常是用来打印当前非阻塞赋值的变量值的。

4,$monitor

$monitor 为监测任务,用于变量的持续监测。只要变量发生了变化,$monitor 就会打印显示出对应的信息。 其使用方法与 $display一致。

下面的代码用$monitor 来实现监控a,b,c这3个变量,只要其中一个发生了变化,就会立马在终端打印。


`timescale 1ns/1ns
 
module test_tb();
 
reg [1:0]  a ;
reg [1:0]  b ;
reg [1:0]  c ;
 
initial begin
    a = 0 ;
    b = 0 ;
    c = 0 ;
 
    $monitor("a=%d b=%d c=%d",a,b,c);
    #50 $finish;    //50ns后停止
end
 
always #10 begin        //每10ns,随机生成a,b,c
    a = {$random}%4;
    b = {$random}%4;
    c = {$random}%4;
end
 

终端打印结果如下:

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

5,$fopen

  • $fopen:打开指定文件
  • $fclose:关闭指定文件
integer        handle1;                                 //定义句柄1
handle1 = $fopen("file_name",type)       //以指定类型(type)的方式来打开文件,并将其返回值赋给handle

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

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

6,$fdisplay, $fwrite,$fstrobe,$fmonitor

这4个函数都可以对指定文件进行打印或写入操作,其用法与对应的$display, $write,$strobe,$monitor几乎一致。建议参考以上用法

区别在于$display等函数是直接在仿真中进行打印,而$fdisplay等函数是对指定文件进行打印,需要通过句柄来指定是对具体哪个文件进行操作。如:

        reg                data;

        integer        handle1;                                                         //定义句柄1

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

//对指定文件写入数据

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

7,$fclose

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

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

8,$readmemh和$readmemb

$readmemh(h,hexadecimal,十六进制)用来读取16进制的数据

$readmemb(b,binary,二进制)则用来读取2进制的数据。

$readmemb("<数据文件名>",<数组名>)

$readmemb ("<数据文件名>",<数组名>,<起始地址>)

$readmemb ("<数据文件名>",<存贮器名>,<起始地址>,<结束地址>)

$readmemh("<数据文件名>",<数组名>)

$readmemh ("<数据文件名>",<数组名>,<起始地址>)

$readmemh ("<数据文件名>",<数组名>,<起始地址>,<结束地址>)

使用方法1:不指定起始地址和结束对应地址

$readmemh("<数据文件名>",<数组名>)


`timescale 1ns / 1ns
 
module tb_read_test();
 
integer i;     
reg [7:0] mem_test [9:0];        //mem_test是位宽8bit,个数为10的数组
 
initial $readmemh("D:/read_test/read_test.srcs/sim_1/new/data.txt",mem_test);    //绝对路径
 
//显示数组的10个值
initial begin
    for(i=0; i<10; i=i+1)
        $display("%d: %h", i, mem_test[i]);
end

仿真结果如下:

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

  1. 去除部分数据文件中的数据,导致数组无法被填满(注释掉后面4个数据):

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

仿真结果如下:

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

数据文件仅有6个数据,而数组个数为10,所以数组的后4个数据仍没有被赋值。

使用方法2:指定起始地址,但不指定结束地址

即$readmemh ("<数据文件名>",<数组名>,<起始地址>),此时会将从数据文件中读到的第1个数据填入数组的起始地址,此后类推,直到数组被填满。而之前被起始地址跳过的数组的数据则不会被赋值。如果数据的个数大于数据文件中数据的个数,则数组无法被填满,未被填满的部分则依然是未知状态。

指定数据从数组的地址2开始赋值,则地址2应该被赋值0,地址3被赋值1,···等等。而地址0和地址1则仍保持未赋值状态:

`timescale 1ns / 1ns
 
module tb_read_test();
 
integer i; 
reg [7:0] mem_test [9:0];//mem_test是位宽8bit,个数为10的数组
 
initial $readmemh("D:/read_test/read_test.srcs/sim_1/new/data.txt",mem_test,2);//绝对路径,从地址2开始
 
//显示数组的10个值
initial begin
for(i=0; i<10; i=i+1)
$display("%d: %h", i, mem_test[i]);
end
 
endmodule

仿真结果如下:

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

从地址2开始依次被赋值00~07,而地址0和地址1则仍保持未赋值状态。

使用方法3:同时指定起始地址和结束地址

即$readmemh ("<数据文件名>",<数组名>,<起始地址>,<结束地址>),此时会将从数据文件中读到的第1个数据填入数组的起始地址,此后类推,直到指定的终结地址对应的数组也被赋值。处于起始地址和终结地址构成的区间范围外的地址对应的数组则不会被赋值。如果数据的个数大于数据文件中数据的个数,则数组无法被填满,未被填满的部分则依然是未知状态。

指定数据从数组的地址2开始赋值,直到地址8终结,则地址2应该被赋值0,地址3被赋值1,···等等,直到地址8也被赋值。而地址0、1、9则仍保持未赋值状态:

`timescale 1ns / 1ns
 
module tb_read_test();
 
integer i; 
reg [7:0] mem_test [9:0];//mem_test是位宽8bit,个数为10的数组
 
initial $readmemh("D:/read_test/read_test.srcs/sim_1/new/data.txt",mem_test,2,8);//绝对路径,从地址2开始
 
//显示数组的10个值
initial begin
for(i=0; i<10; i=i+1)
$display("%d: %h", i, mem_test[i]);
end
 
endmodule

仿真结果如下:

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

从地址2开始直到地址8依次被赋值00~06,而地址0、1、9则仍保持未赋值状态。

9,parameter、localparam的区别和用法

一、区别

parameter: 可以在实例化时修改参数值

localparam:只能在当前模块使用,不能进行实例化

二、用法

2.1 设计文件中parameter的用法

直接在模块名后面 #(parameter 参数名=参数值)

2.2 例化模块时parameter的用法

在模块名后面直接 #(.参数名 (参数值))

实列操作

需求1:

雷码转换设计的仿真测试结果写入txt文本

使用绝对路径(注意绝对路径下的文件夹命名都要遵循verilog变量命名规范)

需求分析:

1,创建文件夹,创建文件

2,将内容写入文件

3,关闭文件

`timescale 1ns/1ps
module testbench_top();


//参数定义
 `define CLK_PERIORD 20    

 
//接口申明
reg i_clk;
reg i_rst_n;
reg i_en;
reg[9:0] i_data;
wire o_vld;    //有效信号
wire[15:0] o_data;

vlg_design vlg_design_inst (
    .i_clk(i_clk),
    .i_rst_n(i_rst_n),
    .i_en(i_en),
    .i_data(i_data),
    .o_vld(o_vld),
    .o_data(o_data) 
    );        
    
integer i;

initial  begin
i_en <= 0;
i_clk <= 0;
i_rst_n <= 0;
i_data <= 0;
#2000;
i_rst_n <= 1;
end

always #(`CLK_PERIORD/2) i_clk = ~i_clk;

//产生激励
initial begin
    @(posedge i_clk);
    @(posedge i_rst_n);    
    i_en <= 1;
    @(posedge i_clk);    
    for (i = 1;i <= 1024;i = i+1) begin
        i_data <= i;
        @(posedge i_clk);
    end
    @(posedge i_clk);
    i_en <= 0;
    #50_000;
    $fclose(handle1);  //关闭文件
    $stop;
end

//实时显示,并写入文件
always@(posedge i_clk) begin
    if(o_vld) begin
        $display("%d",o_data);
        $fdisplay(handle1,"%d",o_data);  //往handle1 句柄的文件中写入文件
    end
    else ; 
end
//创建file_test1.txt 文件
integer   handle1; //定义句柄1
initial begin
  //以w类型(写)的方式来打开文件,并将其返回值赋给handle1  
  //使用绝对路径(注意绝对路径下的文件夹命名都要遵循verilog变量命名规范)
  //注意绝对路径的文件夹要存在,文件可以新生成,即先手动新建outputfile 文件夹
  handle1 = $fopen("./outputfile/file_test1.txt","w");   
end

endmodule

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

verilog fwrite连续打印,verilog &amp;FPGA,fpga开发,学习

需求2:

txt文本文件中8位格雷码数据的读取与使用文章来源地址https://www.toymoban.com/news/detail-769952.html

/
//EDA工具平台:Vivado 2019.1 + ModelSim SE-64 10.5 
//开发套件型号: STAR 入门FPGA开发套件
//版   权  申   明: 本例程由《深入浅出玩转FPGA》作者“特权同学”原创,
//                仅供特权同学相关FPGA开发套件学习使用,谢谢支持
//官方淘宝店铺: http://myfpga.taobao.com/
//微 信 公 众 号:“FPGA快乐学习”
//                欢迎关注,获取更多更新的FPGA学习资料 
/
`timescale 1ns/1ps

module testbench_top();
    

//参数定义

`define CLK_PERIORD        10        //时钟周期设置为10ns(100MHz)    
parameter GRAY_MSB    = 7;



//接口申明
    
reg clk;
reg rst_n;
reg i_en;
reg[GRAY_MSB:0] i_data;
wire o_vld;
wire[GRAY_MSB:0] o_gray;

    
//对被测试的设计进行例化
    
vlg_design    #(
    .MSB(GRAY_MSB)
)    
uut_vlg_design(
    .i_clk(clk),
    .i_rst_n(rst_n),
    .i_en(i_en),
    .i_data(i_data),
    .o_vld(o_vld),
    .o_gray(o_gray)
    );    
    

//复位和时钟产生

    //时钟和复位初始化、复位产生
initial begin
    clk <= 0;
    rst_n <= 0;
    #1000;
    rst_n <= 1;
end
    
    //时钟产生
always #(`CLK_PERIORD/2) clk = ~clk;


//文本文件的读取
reg[7:0] data_mem[255:0];

initial $readmemb("./input_file/8bit_grayencode.txt",data_mem);
    


//测试激励产生

initial begin
    i_en <= 'b0;
    i_data <= 'b0;
    $display("The value of GRAY_MSB is %0d",GRAY_MSB);
    @(posedge rst_n);    //等待复位完成
    
    @(posedge clk);
    i_en <= 'b1;
    i_data <= 'b0;    
    
    repeat(2**(GRAY_MSB+1)-1) begin
        @(posedge clk);
        i_en <= 'b1;
        i_data <= i_data+1;
    end
    @(posedge clk);
    i_en <= 'b0;
    #100;
    
    //$fclose(wfile);
    
    $stop;
end

/*integer wfile;

initial begin
    wfile = $fopen("./output_file/result_data.txt","w");
end*/

integer cnt;

always @(posedge clk) begin
    if(!rst_n) cnt <= 0;
    else if(o_vld) cnt <= cnt+1;
end

always @(posedge clk) begin
    if(o_vld) $display("%b\n%b\n\n",o_gray,data_mem[cnt]);
end
endmodule

到了这里,关于【FPGA/verilog -入门学习11】verilogTestbench中的文本文件写入,读出,打印等操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA/verilog -入门学习10】verilog 查表法实现正弦波形发生器

    用查找表设计实现一个正弦波形发生器 寻址的位宽是10位,数据量是1024个,输出的数据是16位 数据量是1024个: x = linspace(0,2*pi,1024) 输出数据是16位: y范围:0~2^16 -1 = 0~65535 y =( sin(x)+1)*65535/2 寻址的位宽是10位 输入是0~1023 1023 占用10位 操作步骤 1,使用matlab 生成数据,制作

    2024年02月05日
    浏览(50)
  • FPGA/Verilog HDL/AC620零基础入门学习——第一个项目按键控制LED

    最近要考试了,所以我赶紧补习FPGA,我们用的是小梅哥的AC620开发板,软件是Quartus。推荐看这个视频教程:零基础轻松学习FPGA,小梅哥FPGA设计思想与验证方法视频教程 用按键控制LED灯的亮灭就是一个二选一多路器,两个IO,a、b,可以是高电平,也可以是低电平。 输入按键

    2024年02月05日
    浏览(45)
  • 【FPGA】Verilog设计入门——时序模块及其Verilog表述

    目录 1.边沿触发型触发器及其Verilog表述 2.电平触发型锁存器及其Verilog表述  3.含异步复位/时钟使能型触发器及其Verilog表述 4.同步复位型触发器及其Verilog表述  5.异步复位型锁存器及其Verilog表述 6.Verilog的时钟过程表述的特点和规律   7.异步时序模块的Verilog表述  8.4位二进制

    2024年02月07日
    浏览(32)
  • 【FPGA入门】第一篇、Verilog基本语法常识

    目录 第一部分、不同的变量类型 1、wire和reg的区别  2、如何对变量进行赋值呢? 3、什么是阻塞?什么是非阻塞? 第二部分、变量位宽的定义 1、各种系统默认情况 2、变量位宽声明方式 3、表明位宽的情况下,赋值方式 4、两个模块之间例化,不定义变量直接用的方式 5、常

    2024年02月04日
    浏览(41)
  • FPGA高端项目:纯verilog的 UDP 协议栈,提供11套工程源码和技术支持

    FPGA高端项目:纯verilog的 UDP 协议栈,提供11套工程源码和技术支持 目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但中间的FIFO或者RAM等调用了IP,或者不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,

    2024年02月03日
    浏览(43)
  • FPGA中的流水线设计(含Verilog范例)

    在高速通信系统设计中,如何提高系统的工作速度至关重要,通常使用的方法有两种: 1. 并行方式设计:可减少模块间的延时; 2. 流水线设计:流水线设计如同生产线一样,将整个执行过程分解为若干个工作段,从流水线的起点连续输入,各操作段以重叠方式执行。使得运

    2023年04月21日
    浏览(27)
  • 【FPGA基础入门实践】Verilog 基本项目操作逐步演示

    0x00 回顾:AND/OR/NOT 逻辑的特性 AND: 与门可以具有两个或更多的输入,并返回一个输出。当所有输入值都为 1 时,输出值为 1。如果输入值中有任何一个为 0,则输出值为 0。 OR: 或门可以具有两个或更多的输入,并返回一个输出。如果输入值中至少有一个为 1,则输出值为

    2024年02月12日
    浏览(32)
  • Verilog force语句详解:FPGA中的信号强制赋值

    Verilog force语句详解:FPGA中的信号强制赋值 在FPGA开发中,时序分析和调试是非常重要的一部分。其中,对于一些信号的调试,我们需要准确地模拟不同的情况来检测其工作状态。这时,Verilog force语句就起到了重要的作用。 force语句可以使信号立即进行强制赋值操作,在仿真

    2024年02月06日
    浏览(32)
  • 【数字IC/FPGA】Verilog中的force和release

    在Verilog中,将 force 用于variable会覆盖掉 过程赋值 ,或者assign引导的 连续(procedural assign)赋值 ,直到 release 。 下面通过一个简单的例子展示其用法: 加法器代码 测试平台代码(主要用于产生激励) 如上所示,正常情况下,u_adder模块的a和b端口由testbench中的a和b信号驱动,

    2024年02月09日
    浏览(36)
  • Verilog & FPGA学习(一)

            最近心血来潮买了一块fpga,来自spieed的Tang Nano 9K,基于高云半导体 GW1NR-9 FPGA芯片。         其实之前买过一块紫光的fpga,但是嫌环境配置太麻烦就搁置了,这次换了一家的fpga,环境配置很快,直接用高云的gowin编译器就能很快实现程序编写与下载。但是这两天

    2024年01月17日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包