推广 热搜: csgo  vue  2023  angelababy  gps  信用卡  新车  htc  落地  控制 

fopen读取数后存入数组 (Testbench用法总结)1

   2023-08-27 网络整理佚名1760
核心提示:数据存入mem但还没有进入到模块的输入,接下来的操作可以参考下列代码:用法与C语言类似,文件句柄为第一个参数,第二个参数为格式参数,第三个为数据保存变量,但不需要加&了。数据存储操作如下,在前面fopen使用w模式下:它的文件写入数据之后会自动到下一行,所以第二个参数不需要加入“\n”;ftell等函数。

编写和调试火葬场真是太酷了; 多么深刻地说明了调试在整个设计过程中的重要性,而仿真调试也是调试的重要组成部分。

为了巩固自己的写作技术,也为了和大家交流调试经验,写了这篇文章和大家分享。

本文主要介绍如何读取和存储文本文件中的数据,涉及基本语法。

为了调试和模拟一些数据处理模块,模块需要特定的数据输入,例如单频正弦波; 为了解决这个问题,我们可以使用诸如等工具生成文本数据,然后使用该数据读入; 您可以使用两种方法来操作文本数据

, , , 操作

, 等等

, , , 操作

从字面意思来看,就是读取数据,后缀b和h代表数据的基数; 同样,是将数据写入文件;

因此,在使用此类系统的内置函数时,首先必须有一个类型的变量。 定义方法如下:

reg [M-1:0] mem [N:1];

mem“变量”(应该称为寄存器组)有N个“一维”变量,每个“一维”变量的位宽为M; 你可以将mem理解为C语言中的一个二维数组,其中包含NA个一维数组,每个一维数组有M个元素,元素是位。

事实上,我们称M为mem的数据宽度,N为mem的数据深度。

以数据读取操作为例

initialbegin $readmemb("data.txt", mem);end

第一个参数是文件名,第二个参数是变量名; 至此,data.txt中的N行数据就存储在mem中了。 操作类似,不同的是data.txt中的数据要求是16进制。

那么有人可能会有疑问,如果有以下问题,mem中存储的数据会是什么样的:

图1 数据位宽小于M波形

图2 数据位宽小于M存储

图3 数据位宽大于M

图4 数据位宽大于M,VCS警告

经测试,如果M大于数据位宽,则可以正常读取数据,高位补0; 如果小于数据位宽,则无法正常读取数据。

与M小于数据位宽的情况一致,无法正常读取数据。

图5 行数小于N

图6 行数大于N

经测试,如果行数大于N,模拟器会发出警告,但可以正常读取数据。 当它小于N时,多余部分的值是不确定的。

数据已存储在mem中,但尚未进入模块的输入。 接下来的操作可以参考下面的代码:

reg [M-1:0] data_in;integer index = 1;
initialbegin forever begin @(posegde clk); data_in = mem[index]; index = (index >= N) ? 1 : index + 1; endend

代码中,等待clk的上升沿,然后将mem的索引元素赋值给 ,然后完成索引加1的操作; 整个过程不断循环; 这里设置索引计数到N返回1的计数保护,防止无效数据出现。

然后连接到被测模块的数据输入口,数据就会发送进来。

图7 发送的数据波形

操作并依次将mem的数据存储为文本如下:

initialbegin    $writememb("new_data_b.txt", mem);    $writememh("new_data_h.txt", mem);end

储存后

图片

图片

, 等等

语法本身与C类似,也具有文本操作功能,也与C类似。要使用文本操作,首先需要执行以下操作:

integer fid;initialbegin fid = $fopen("data.txt", "r"); //fid = $fopen("data.txt", "w"); //write if (!fid) $display("file open error");end

像C语言中的fopen,第一个参数是文件名,第二个参数是操作模式,包括读(r,rb)、写(w,wb)等操作; 根据返回值判断文件操作是否有错误。

然后根据文本文件的数据格式,进行数据读取操作。

reg [M-1:0] data_in;
always @ (posedge clk) $fscanf(fid, "%d %d %d", data_in, mem[0], mem[1]);

用法和C语言类似,第一个参数是文件句柄,第二个参数是格式参数,第三个是数据存储变量,但是不需要加&。 读取文件时,第二个参数和第三个参数需要对应,否则读取的数据可能错误。 (个人经验)

数据存储操作如下,之前fopen中使用w模式:

always @ (posegde clk) $fwrite(fid, "%d, %d, %d\n", $signed(data_in), $signed(data_in)+1, $signed(data_in)+2);

数据可以按照第二个参数的格式存储在文本文件中。 还有一系列比如,相对来说,它的文件写入数据后会自动转到下一行,所以第二个参数不需要加“\n”; ftell 等功能。

注意,如果要以十进制存储负数,除了第二个参数使用%d外,第三个参数的寄存器变量也必须使用$转换为有符号数

图10 正常情况下读取文本操作后存储的数据

图11 当寄存器位宽小于数据位宽时,读取文本操作后存储的数据

注意,当存储的寄存器位宽小于数据位宽时,数据会自动截断,保留高位。

当我使用文件操作来存储被测模块的输出时,每个文件中的数据量(行)与理想数量不匹配。 经过查找各种原因,最后发现是我犯了低级错误,没有使用close。 文件句柄。

initial begin #1000; $fclose(fid); $finish;end

在停止仿真之前,一定要关闭文件句柄,否则数据访问会出现不可预知的问题。

欢迎使用本文中使用的实验。 注意,使用下面的实验时,文件名必须是绝对路径; 在tb中,使用“”宏定义来判断操作还是文件操作,可以尝试修改宏定义的值来改变文件操作的函数类型;本文使用的资源可以从官方获取账号回复116;

两种方法的差异比较

,该方法只能访问二进制或十六进制数据,数据格式固定,不支持读取其他格式的多维数据,文件操作不灵活; 文本操作方便其他工具,比如处理数据

它是可综合语句,因此可以用来给模块中的变量赋值,但其他语句不是可综合语句,只能用于模拟测试

文件操作虽然支持各种格式的文本访问,但操作简单、简单; 如果需要回收数据,读取后可以通过重置索引来回收数据,而文本操作比较麻烦。

另外想问一下大家学习UVM有没有更好的学习资源或者学习方法。

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON