zoukankan      html  css  js  c++  java
  • [转]c fscanf 按行读取文件_(Testbench用法总结)1. Testbench中文本数据的存储读取操作对比...

    本文转自:(8条消息) c fscanf 按行读取文件_(Testbench用法总结)1. Testbench中文本数据的存储读取操作对比..._weixin_40001309的博客-CSDN博客

    写时一时爽,调试火葬场;多么深刻的说明了在整体设计过程中,调试所占据的重要性,而仿真调试也是调试里面重要的一环。

    为了巩固自己的Testbench编写技术,为了与大家交流调试经验,写出这篇文章与大家共同交流。

    本文主要讲述Testbench中如何读取和存储文本文件的数据,涉及到基础的Verilog语法。


     对一些数据处理的模块进行调试仿真,模块需要特定的数据输入,比如单一频率的正弦波;为了解决这个问题,我们可以用matlab,python等工具生成文本数据,然后使用Verilog将数据读取进来;Testbench可以使用2种方法进行文本数据操作

    1. readmemb, readmemh, writememb, writememh操作
    2. fscanf, fwrite等操作

    readmemb, readmemh, writememb, writememh操作 从字面意思理解,readmem是读取数据到memory,后缀的b, h代表了数据的进制;同理,writemem是将memory的数据写入到文件中; 所以,在使用这一类系统自带函数时,首先要有一个memory类型的变量。定义方法如下:

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

    mem”变量“(应该叫寄存器组)有N个”一维“变量,每个”一维“变量的bit宽度为M;你可以将mem理解为C语言中的二维数组,里面包含了N个一维数组,每个一维数组有M个元素,元素为bit。 事实上,我们称M为mem的数据宽度,N为mem的数据深度。 以readmemb为例,进行数据读取操作

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

     readmemb的第一个参数为文件名,第二个参数为memory变量名;至此,data.txt内部的N行数据存入了mem里。readmemh操作类似,不同的是data.txt的数据要求为16进制。 那么可能有人会有疑问了,假如有以下问题,mem存入的数据会是啥样:

    • data.txt每行的数据位宽小于M或者大于M

    7bb77c2bfe1d875f6cc8570fc8a712e1.png

    图1 数据位宽小于M波形

    37da6fe8e2f9e9aae77b33c22638229a.png

    图2 数据位宽小于M存储

    bf1b595dc12174a821e3cdc6d3e4f427.png

    图3 数据位宽大于M

    4d3dc2fd6f7374cd893f209c897578e9.png

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

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

    • data.txt的数据不是二进制,或者不是纯数字

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

    • 如果data.txt的行数小于N或大于N

    91ea294587533ea469909f8092e3963d.png

    图5 行数小于N

    d053bd9a3d80e60276629e50e28950bc.png

    图6 行数大于N

    经过试验,行数大于N,仿真器会出警告,但数据可以正常读取。小于N时,多余的部分memory的值为不定状态。 数据存入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的index元素赋值给data_in,然后index完成加1操作;整个过程不断循环;这里设置了index计数到N返回1的计数保护,防止出现无效数据。 再将data_in与被测模块的数据输入端口相连,数据就送入进去了。

    c0b8be7d9c31bd783f824890ed9f6124.png

    图7 送入的数据波形

    writememb的操作与readmemb反过来,将mem的数据存储为文本操作如下:

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

    存储之后的

    80176ca044e58d9afaef2b54e41e1c0a.png

    图8 writememh

    2d2712bbb956ab85ebc26c2131f9823b.png

    图9 writememb

    fscanf, fwrite等操作 Verilog本身的语法与C类似,其自身也有文本操作的函数,也与C类似。使用Verilog对文本操作,首先需要进行如下操作:

    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]);

    fscanf用法与C语言类似,文件句柄为第一个参数,第二个参数为格式参数,第三个为数据保存变量,但不需要加&了。读取文件的时候第二个参数与第三个参数需要对应,否则数据读取可能会出错。(亲身经历) 数据存储操作如下,在前面fopen使用w模式下:

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

    数据可以按照第二个参数的格式存储进文本文件。还有一系列如fdisplay, 相对于fwrite, 它的文件写入数据之后会自动到下一行,所以第二个参数不需要加入“ ”;ftell等函数。 注意,想要存储十进制的负数,除了第二个参数用%d,第三个参数的寄存器变量还要使用$signed转换为有符号数形式

    87db13688d4daf537afa5f14059efa19.png

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

    ec4841e61ee05204a7d2d317bf30ac1b.png

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

    注意,当存储的寄存器位宽小于数据位宽时,数据会被自动截去高位保留低位。 之前使用文件操作存储被测模块的输出时,每次文件的数据量(行数)都与理想中的数目对不上,找各种原因,最后才发现自己犯了一个低级错误,没有使用fclose关闭文件句柄。

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

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

    欢迎使用本文使用的Testbench做实验,注意,在windows下使用modelsim做实验时,文件名必须是绝对路径;tb中,使用"READMEM_ON"宏定义决定运行readmem或文件操作,可以尝试修改宏定义的值改变文件操作的函数类型;本文使用资源在公众号回复116获取;

    两种方法差异对比

    1. readmem,writemem方法只能存取二进制或十六进制数据,数据格式固定,对多维其他格式数据读取不支持,没有文件操作灵活;文本操作方便其他的工具,如matlab,python处理数据
    2. readmem是可综合语句,所以可以用于对模块内的memory变量进行赋值,但其他语句是不可综合语句,只能用于仿真测试中
    3. 文件操作虽然支持各种格式的文本存取,但是操作上没有readmem, writemem简单;假如数据需要循环使用,readmem读取进memory之后,通过复位index就可以循环使用数据,而文本操作就麻烦一些。
  • 相关阅读:
    Realtime crowdsourcing
    maven 常用插件汇总
    fctix
    sencha extjs4 command tools sdk
    首次吃了一颗带奶糖味的消炎药,不知道管用不
    spring mvc3 example
    ubuntu ati driver DO NOT INSTALL recommand driver
    yet another js editor on windows support extjs
    how to use springsource tools suite maven3 on command
    ocr service
  • 原文地址:https://www.cnblogs.com/jason20/p/15504550.html
Copyright © 2011-2022 走看看