Verilog的系统任务----$readmemh和$readmemb

这篇具有很好参考价值的文章主要介绍了Verilog的系统任务----$readmemh和$readmemb。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

        这两个系统任务是用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了可以在仿真的任何时刻被执行使用外,根据综合工具的不同,也可以用来对RAM或者ROM进行初始化(Vivado支持)。

        使用格式共6种:

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

        $readmemh(h,hexadecimal,十六进制)用来读取16进制的数据,而$readmemb(b,binary,二进制)则用来读取2进制的数据。       

        由于$readmemh与$readmemb的用法几乎一样,仅仅是读取数字的进制不同。所以下文均已$readmemh来阐述这两个系统任务的用法。


用法示例

        下面具体说说这两个系统任务的用法,并结合仿真工具进行仿真测试来辅助说明。

数据文件的格式

        在这两个系统任务中,被读取的数据文件的内容只能包含:空白位置(空格、换行、制表格、注释行、二进制或十六进制的数字。数字中不能包含位宽说明和格式说明,对于$readmemb和$readmemh系统任务,每个数字可以是二进制或者十六进制数字。另外,数字必须用空白位置或注释行来分隔开。

        比如文件data.txt用来表示10个8bit的16进制数据,可以这么表示(每个数据占一行):

Verilog的系统任务----$readmemh和$readmemb

        也可以这么表示(每个数据用空格隔开): 

Verilog的系统任务----$readmemh和$readmemb

        还可以用@+地址的方式来跳跃式地指定某一个地址的数据内容(不太建议使用):

Verilog的系统任务----$readmemh和$readmemb


数据文件的路径表示方法

        可以用两种路径表示方法来指导综合工具找到你的数据文件:1、绝对路径;2、相对路径。

(1)绝对路径

        绝对路径就是数据文件在系统中的位置,比如:

Verilog的系统任务----$readmemh和$readmemb

        数据文件data.txt的绝对路径就是 D:\read_test\read_test.srcs\sim_1\new 

        但是一定需要注意的是,尽管在windows系统中使用斜杠 \ 来表示不同的层级,但是在系统函数$readmemh中取需要使用反斜杠 / 来表示层级,如下:

                $readmemh("D:/read_test/read_test.srcs/sim_1/new/data.txt",mem_test);        //绝对路径

        这样综合工具就会去这个目录下寻找数据文件。

(2)相对路径

        相对路径是根据仿真文件或者RTL文件的位置来相关的。

        比如在vivado中使用系统函数$readmemh时采用如下表示方法:

                $readmemh("data.txt",mem_test);        //相对路径

        同时,数据文件必须放在这个路径下:

Verilog的系统任务----$readmemh和$readmemb

        综合工具就会直接去该目录下寻找数据文件,如果该目录下没有指定的数据文件,则会发出警告,同时仿真读取的值都是x。modelsim的相对路径貌似宽松一点,但没具体测试过,不多说。

        从这,也可以看到,使用绝对路径其实要灵活一点,从不同的平台迁移会比较方便,所以建议使用绝对路径。


使用方法:

        接下来分别对$readmemh的三种使用方法做个仿真测试和介绍,使用的数据文件data.txt如下:

Verilog的系统任务----$readmemh和$readmemb


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

        即$readmemh("<数据文件名>",<数组名>),此时会将从数据文件中读到的第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);	//绝对路径

//显示数组的10个值
initial begin
	for(i=0; i<10; i=i+1)
		$display("%d: %h", i, mem_test[i]);
end
 	
endmodule

        仿真结果如下: 

Verilog的系统任务----$readmemh和$readmemb

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

Verilog的系统任务----$readmemh和$readmemb

        仿真结果如下:

Verilog的系统任务----$readmemh和$readmemb

        数据文件仅有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的系统任务----$readmemh和$readmemb

        从地址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的系统任务----$readmemh和$readmemb

        从地址2开始直到地址8依次被赋值00~06,而地址0、1、9则仍保持未赋值状态。 文章来源地址https://www.toymoban.com/news/detail-465208.html


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

到了这里,关于Verilog的系统任务----$readmemh和$readmemb的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Verilog 教程】6.2Verilog任务

    :任务 任务与函数的区别 和函数一样,任务(task)可以用来描述共同的代码段,并在模块内任意位置被调用,让代码更加的直观易读。函数一般用于组合逻辑的各种转换和计算,而任务更像一个过程,不仅能完成函数的功能,还可以包含时序控制逻辑。下面对任务与

    2024年02月07日
    浏览(31)
  • Testbench关于$readmemh读取数据异常问题

    1、前言         笔者最近在进行DDR3方面的仿真验证工作,为了验证DDR是否读写正常,激励中产生八个通道的视频源数据,通过DDR初始信号、视频源场信号控制输入。         仿真时看起来输入的数据及相关波形都是正常的,但是这种验证只看输入是没有用处的,还是得看具

    2024年02月01日
    浏览(21)
  • Verilog中的任务Task和函数Function

    task和function说明语句分别用来定义任务和函数。 利用任务和函数可以把一个很大的程序模块分解成许多较小的任务和函数便于理解和调试。 输入、输出和总线信号的值可以传入、传出任务和函数。任务和函数往往还是大的程序模块中在不同地点多次用到的相同的程序段。 学

    2023年04月26日
    浏览(27)
  • day10-verilog---模块的调用,任务和函数

    在做模块划分时,通常会出现这种情形,某个大的模块中包含了一个或多个功能子模块,verilog是通过 模块调用 或称为 模块实例化 的方式来实现这些子模块与高层模块的连接的 调用模块实例化的一般形式为: 模块名参数列表实例名(端口列表); 其中参数列表是传递到子

    2024年02月02日
    浏览(29)
  • Verilog语法之任务Task与函数Function

    目录 1、概述 2、任务 task 2.1、任务的定义 2.2、一个task例子 3、函数 function 3.1、函数的定义 3.2、一个function例子 4、任务与函数的异同 5、总结与参考         与C语言中的函数类似,在Verilog代码中,通过把代码分成小的模块或者使用 任务(task) 和 函数(function) ,可把一

    2024年02月15日
    浏览(25)
  • Verilog 显示任务($display, $write, $strobe, $monitor)

    Verilog 中主要用以下 4 种系统任务来显示(打印)调试信息: $display, $write, $strobe, $monitor。 $display $display 使用方法和 C 语言中的 printf 函数非常类似,可以直接打印字符串,也可以在字符串中指定变量的格式对相关变量进行打印。例如: 如果没有指定变量的显示格式,变量值

    2023年04月15日
    浏览(65)
  • 【Verilog数字系统设计(夏宇闻)4-----Verilog语法的基本概念2】

    下面先介绍几个简单的Verilog HDL程序,从中了解Verilog模块的特性。 例1 如图所示的二选一多路选择器的Verilog HDL程序如下: 从例1中很容易理解模块muxtwo的作用。它是一个如图所示的二选一多路器,输出out与输入a一致,还是与输入b一致,由sl的电平决定。当控制信号sl为非(低

    2023年04月08日
    浏览(30)
  • Verilog系统函数

    在Verilog HDL语言中每个系统函数和任务前面都用一个标识符 $ 来加以确认。这些系统函数和任务提供了非常强大的功能。 在ModelSim仿真时添加系统函数利于调试。 $width函数用于检查信号脉冲的宽度是否达到要求。而信号脉冲的宽度由信号的reference_event和data_event决定,如下图所

    2024年02月11日
    浏览(20)
  • Linux 系统下 “Verilog” 编程配置

    Verilog HDL 是一种用于设计数字电路的硬件描述语言,它可以用来描述数字电路的功能和结构,并且可以被编译器转换成可以在现实世界中运行的电路。 Verilog HDL语言 由一系列的、表达式和语句组成,这些元素可以用来描述电路的输入、输出和内部状态。 Iverilog 是一种

    2024年02月15日
    浏览(23)
  • 【系统设计】Verilog语法及示例(1)

    参考Verilog语法 | 教程 (ustc.edu.cn) Verilog HDL 是一种 硬件描述语言 (Hardware Description Language),以文本形式来描述 数字系统硬件的结构和行为 的语言,用它可以表示 逻辑电路图、逻辑表达式 ,还可以表示 数字逻辑系统所完成的逻辑功能 。 Verilog HDL和VHDL是世界上最流行的两种

    2024年02月06日
    浏览(26)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包