【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

2,$write

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

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

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

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

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 

总结:$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/1nsmodule test_tb();reg [1:0]  a ;
reg [1:0]  b ;
reg [1:0]  c ;initial begina = 0 ;b = 0 ;c = 0 ;$monitor("a=%d b=%d c=%d",a,b,c);#50 $finish;    //50ns后停止
endalways #10 begin        //每10ns,随机生成a,b,ca = {$random}%4;b = {$random}%4;c = {$random}%4;
end

终端打印结果如下:

5,$fopen

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

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;                                                         //定义句柄1handle1 = $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 / 1nsmodule 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 beginfor(i=0; i<10; i=i+1)$display("%d: %h", i, mem_test[i]);
end

仿真结果如下:

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

仿真结果如下:

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

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

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

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

`timescale 1ns / 1nsmodule 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]);
endendmodule

仿真结果如下:

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

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

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

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

`timescale 1ns / 1nsmodule 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]);
endendmodule

仿真结果如下:

从地址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;
endalways #(`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) begini_data <= i;@(posedge i_clk);end@(posedge i_clk);i_en <= 0;#50_000;$fclose(handle1);  //关闭文件$stop;
end//实时显示,并写入文件
always@(posedge i_clk) beginif(o_vld) begin$display("%d",o_data);$fdisplay(handle1,"%d",o_data);  //往handle1 句柄的文件中写入文件endelse ; 
end
//创建file_test1.txt 文件
integer   handle1; //定义句柄1
initial begin//以w类型(写)的方式来打开文件,并将其返回值赋给handle1  //使用绝对路径(注意绝对路径下的文件夹命名都要遵循verilog变量命名规范)//注意绝对路径的文件夹要存在,文件可以新生成,即先手动新建outputfile 文件夹handle1 = $fopen("./outputfile/file_test1.txt","w");   
endendmodule

需求2:

txt文本文件中8位格雷码数据的读取与使用

/
//EDA工具平台:Vivado 2019.1 + ModelSim SE-64 10.5 
//开发套件型号: STAR 入门FPGA开发套件
//版   权  申   明: 本例程由《深入浅出玩转FPGA》作者“特权同学”原创,
//                仅供特权同学相关FPGA开发套件学习使用,谢谢支持
//官方淘宝店铺: http://myfpga.taobao.com/
//微 信 公 众 号:“FPGA快乐学习”
//                欢迎关注,获取更多更新的FPGA学习资料 
/
`timescale 1ns/1psmodule 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 beginclk <= 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 begini_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 beginwfile = $fopen("./output_file/result_data.txt","w");
end*/integer cnt;always @(posedge clk) beginif(!rst_n) cnt <= 0;else if(o_vld) cnt <= cnt+1;
endalways @(posedge clk) beginif(o_vld) $display("%b\n%b\n\n",o_gray,data_mem[cnt]);
end
endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/269505.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 出现问题:git提交commit时Perform code analysis卡住解决方案

问题 git提交commit时Perform code analysis卡住很久 解决方案一 1、打开 IntelliJ IDEA&#xff0c;进入 File -> Settings&#xff08;或者使用快捷键 CtrlAltS&#xff09;。 2、在弹出的 Settings 窗口中&#xff0c;找到 Version Control -> Commit Dialog 选项…

Chrome谷歌浏览器安装VUE调试插件

访问gitee的vue-devtools 并下载 gitee地址&#xff1a;https://gitee.com/zhang_banglong/vue-devtools 也可以访问git的地址&#xff1a;https://github.com/vuejs/devtools 解压&#xff0c;放到自己的目录下 打开控制面板&#xff08;管理员&#xff09;&#xff0c;进入…

C语言之函数

目录 main函数和库函数 什么是函数 函数定义 函数头&#xff08;function header&#xff09; 1.返回类型&#xff08;return type&#xff09; 2.函数名&#xff08;function name&#xff09; 3.形参声明&#xff08;parameter type list&#xff09; 函数体&#xff…

使用Nacos作为配置中心

Nacos配置中心简介 首先我们来看一下,微服务架构下关于配置文件的一些问题&#xff1a; 配置文件相对分散。在一个微服务架构下&#xff0c;配置文件会随着微服务的增多变的越来越多&#xff0c;而且分散 在各个微服务中&#xff0c;不好统一配置和管理。配置文件无法区分环境…

Day18JAVA

异常 异常:异常就是代表程序出现的问题 误区:不是让我们以后不出现异常,而是程序出现了异常之后,该如何处理 import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date;public class Test {public static void main(String[] args) throw…

go-libp2p-example-chat学习

1.案例下载 https://github.com/libp2p/go-libp2p/tree/master/examples 2.chat案例 这段代码是一个简单的基于libp2p的P2P聊天应用程序的示例。它允许两个节点通过P2P连接进行聊天。前提是&#xff1a; 两者都有私有IP地址&#xff08;同一网络&#xff09;。至少其中一个…

基于ssm校园美食交流系统论文

目 录 摘 要 1 前 言 3 第1章 概述 4 1.1 研究背景 4 1.2 研究目的 4 1.3 研究内容 4 第二章 开发技术介绍 5 2.1Java技术 6 2.2 Mysql数据库 6 2.3 B/S结构 7 2.4 SSM框架 8 第三章 系统分析 9 3.1 可行性分析 9 3.1.1 技术可行性 9 3.1.2 经济可行性 10 3.1.3 操作可行性 10…

python:五种算法(GA、OOA、DBO、SSA、PSO)求解23个测试函数(python代码)

一、五种算法简介 1、遗传算法GA 2、鱼鹰优化算法OOA 3、蜣螂优化算法DBO 4、麻雀搜索算法SSA 5、粒子群优化算法PSO 二、5种算法求解23个函数 &#xff08;1&#xff09;23个函数简介 参考文献&#xff1a; [1] Yao X, Liu Y, Lin G M. Evolutionary programming made…

管理类联考——写作——真题篇——按大小作文分类——小作文

文章目录 56.论证有效性分析&#xff1a;分析下述论证中存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600字左右的文章&#xff0c;对该论证的有效性进行分析和评论。方法20232022202120202019201820172016201520142013 56.论证有效性分析&#xff1a;分析下述论…

java jvm堆内存分析工具MAT(导出运行中jvm堆内存、加载导出文件分析)

下载地址&#xff1a;https://eclipse.dev/mat/downloads.php 历史版本&#xff1a;https://eclipse.dev/mat/previousReleases.php jdk1.8这些老版本jdk需要使用历史版本的&#xff0c;我的是1.8&#xff0c;用的1.10的mat 我下载的地址&#xff1a;https://www.eclipse.org/d…

微服务黑马头条(简略笔记)

Linux中nacos的拉取安装 拉取naocs镜像&#xff1a;docker pull nacos/nacos-server:1.2.0创建容器&#xff1a;docker run --env MODEstandalone --name nacos --restartalways -d -p 8848:8848 nacos/nacos-server:1.2.0访问地址&#xff1a;http://192.168.200.130:8848/n…

聚观早报 |一加12首销;华为智能手表释放科技温暖

【聚观365】12月12日消息 一加12首销 华为智能手表释放科技温暖 卡尔动力获地平线战略投资 英伟达希望在越南建立基地 努比亚Z60 Ultra影像规格揭晓 一加12首销 现在有最新消息&#xff0c;近日一加12该机已于昨日开售&#xff0c;售价4299元起。 外观方面&#xff0c;全…