Testbench关于$readmemh读取数据异常问题

这篇具有很好参考价值的文章主要介绍了Testbench关于$readmemh读取数据异常问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前言

        笔者最近在进行DDR3方面的仿真验证工作,为了验证DDR是否读写正常,激励中产生八个通道的视频源数据,通过DDR初始信号、视频源场信号控制输入。

        仿真时看起来输入的数据及相关波形都是正常的,但是这种验证只看输入是没有用处的,还是得看具体读数据的内容和时序。

        由于采用了3片DDR,所以读取数据的位宽是384位,在modelsim对应的波形一个一个去比对,实在是过于费眼,也不好对比数据是否正常,效率过低。

        所以采用  $fopen  $fwrite  $readmemh  这些系统函数,进行激励中的数据写入以及读出到文本中,再执行数据比对。

2、问题描述

        笔者最初的思路是,定义两个文本,分布存放前一次和当次的读数据,在DDR每次读取数据完成后,进行对比。

        具体操作方法是,利用DDR的 o_mem_rd_end 信号同时执行 两次$readmemh 操作,但是每一次读取出来的数据会出现一个384位宽的数据错误,百思不得其解。

reg  [383:0]  data_read0 [0:511];
reg  [383:0]  data_read1 [0:511];

always @(posedge app_clk) begin
    if (o_mem_rd_end) begin  
        $readmemh   ("read_data0.txt",data_read0,0,511);       
        $readmemh   ("read_data1.txt",data_read1,0,511);       
    end
end

        $readmemh 可用于 initial 以及always 中,乍一看真就是一句简单的从文件中读取十六进制的数据到仿真中而已,语法方面不会出错。

3、解决思路

        由于这个 $readmemh 的错误,导致我所写的自动对比数据的逻辑中,用于比对两次数据的flag一直异常拉低,不好判断数据是否正常,还是得人工手动去放大波形比对数据。对于我这种追(lan)求(de)效(yi)率(pi)的人,是不可以接受的。

        经过定位问题,反复验证后,发现最后还是上面一个代码块的问题,还是 $readmemh 的问题。

        补充一点 $readmemh 的简单用法:

                (1)$readmemh("<数据文件名>",<存储器名>);

                (2)$readmemh("<数据文件名>",<存储器名>,<起始地址>);

                (3)$readmemh("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);

        经过反复的思考后,笔者判断可能是 o_mem_rd_end 这个触发信号多次使用,或者是一个时钟内同时执行两次 $readmemh 出现问题

        最后笔者将 o_mem_rd_end 信号打了两拍进行使用,并且先后进行读操作, $readmemh 数据则正常了

always @(posedge app_clk) begin
    if (o_mem_rd_end0_r) begin  //使用打拍后的信号做判定条件
        $readmemh   ("read_data0.txt",data_read0,0,511);       
    end
    else if (o_mem_rd_end0_rr) begin
        $readmemh   ("read_data1.txt",data_read1,0,511);       
    end

4、相关逻辑代码

        由于将DDR中的数据读取出来,写入文本中,再从文本中读出来进行比对的逻辑不易于直接定位DDR读取数据错误的位置。

        所以更换了逻辑进行测试,同样还是利用两个文本,每次读取数据时交替使用 $fwrite 存储数据。在第一次读取数据时,实时比对第二个文本里面存储的数据,输出比对结果;在第二次读取数据时,实时比对第一个文本里面存储的数据,输出比对结果;以此类推,通过乒乓操作的形式进行实时数据比对。

        芜湖~舒坦! 

        就是在跑仿真时还得手动Zoom Full ,还有DDR3的官方ip核模型跑仿真实在是太慢了。

        

        贴上相关的逻辑代码:

//将modelsim仿真的数据存入文本

wire                rd_req_vio_r;
wire                app_clk; 
wire                o_mem_rd_vld0;   
wire                o_mem_rd_end0;
wire    [383:0]     o_mem_rd_dat0;
reg     [11:0 ]     R_data_cnt;
reg                 rd_req_vio_r_r;
wire                op_f;
reg                 op_count = 0;
reg                 op_r = 0;
wire                oprr;

integer f_id;

    always @(posedge app_clk) begin
        rd_req_vio_r_r <= rd_req_vio_r;
    end

    assign op_f = rd_req_vio_r && ~rd_req_vio_r_r;


    always @(posedge app_clk) begin
        if (op_f && !op_count) begin
            op_r <= 1'b1;                   //选择不同存储位置
            op_count <= 1'b1;
        end
        else if (op_f && op_count) begin
            op_r <= 1'b0;                   //选择不同存储位置
            op_count <= 1'b0;
        end
    end

    assign oprr = op_r;
    
//$fopen的具体路径我已经省去了,注意在这里路径需用反斜杠/ 而不是正常路径的\

    always @(op_r) begin
        if (op_r) begin
            f_id = $fopen("/read_data0.txt","w");      //read_data0.txt
        end
        else if (!op_r) begin
            f_id = $fopen("/read_data1.txt","w");      //read_data1.txt
        end
    end

    always @(posedge app_clk)
        begin
            if (rd_req_vio_r) begin
                if (o_mem_rd_vld0) begin
                    $fwrite(f_id,"%h\n",o_mem_rd_dat0[383:0]);      //写入数据到f_id中
                end
                else if (o_mem_rd_end0) begin
                    $fclose(f_id);
                end
            end
        end
//缓存后 判定跟前一次数据是否相等

reg  [383:0]  data_read0 [0:511];
reg  [383:0]  data_read1 [0:511];
wire [383:0]  data_read0r;
wire [383:0]  data_read1r;
reg  [9:0]    count_data = 0;
reg           data_flag;
reg  [7:0]    data_count = 0;
reg           o_mem_rd_end0_r;
reg           o_mem_rd_end0_rr;
wire          o_mem_rd_end0_rrr;

wire          op_a;//打开第一个文本
wire          op_b;//打开第二个文本   
reg           op_rr;

    always @(posedge app_clk) begin
        op_rr <= op_r;
    end

    assign op_b = ~op_rr && op_r;
    assign op_a = op_rr && ~op_r;

    always @(posedge app_clk) begin
           if (op_b) begin
                $readmemh   ("read_data1.txt",data_read1,0,447);       //读取文件夹中 read_data1 的数据内容
           end
           else if (op_a) begin
                $readmemh   ("read_data0.txt",data_read0,0,447);       //读取文件夹中 read_data0 的数据内容
           end
    end

    always @(posedge app_clk) begin
        if (o_mem_rd_vld0 && op_r) begin
            if (data_read1[count_data] == o_mem_rd_dat0) begin //对比数据是否相同
                data_flag <= 1'b1;            
            end
            else begin
                data_flag <= 1'b0;
            end 
        end
        else if (o_mem_rd_vld0 && !op_r) begin
            if (data_read0[count_data] == o_mem_rd_dat0) begin //对比数据是否相同
                data_flag <= 1'b1;            
            end
            else begin
                data_flag <= 1'b0;
            end
        end
    end

    always @(posedge app_clk) begin
        if (op_a || op_b) begin       //每次数据读取完毕后开始判定
            count_data <= 1'd0;
        end
        else if (count_data == 447) begin      //计数器 判定448个384的数据内容是否相同
            count_data <= count_data;
        end
        else if (o_mem_rd_vld0 && (count_data >= 0) && (count_data < 447)) begin
            count_data <= count_data + 1'd1;
        end
    end

    always @(posedge app_clk) begin
        if (op_a || op_b) begin
            data_count <= data_count + 1'd1;
        end
        else begin
            data_count <= data_count;
        end
    end

    assign data_read0r = data_read0[count_data];
    assign data_read1r = data_read1[count_data];

5、后言

        FPGA实在是太细了,笔者也只是半只鞋丢进了入门的门槛。记录下每个工程中碰到的问题,以供分析及复盘。如有问题,恳请各位批评指正。如有其它疑问可以留言询问。

        注:具体是什么原理导致的问题,我还没有思考出来,以后有想法后再进行补充。文章来源地址https://www.toymoban.com/news/detail-429134.html

到了这里,关于Testbench关于$readmemh读取数据异常问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 关于opencv中cv2.imread函数读取的图像shape问题

    图像坐标系是(w,h),w为x轴,h为y轴,(x,y) 但opencv读出来的数组却正好相反,是(h,w,3),(y,x,3) 所以这里会有一个转换 实则转换为图像坐标系时,要转置一下,或者image.shape[::-1] 切片操作 [start,endstep],其中:- start: 表示开始的下标,如果省略默认为 0 - end: 表示结束的下标(不包含

    2024年02月12日
    浏览(34)
  • 关于k8s中的node_exporter异常write: broken pipe问题排查

    公司网络更改重启服务器后,发现Prometheus监控中node节点三个挂掉了,实际上节点服务器是正常的,但是监控的node_exporter请求http://IP:9100/metrics超过10秒没有获取返回数据则认为服务挂掉。 到各个节点服务器用curl命令检测多久返回数据 time_connect :连接时间,从开始到TCP三次握

    2024年02月10日
    浏览(37)
  • python 图像处理——关于plt.imshow显示cv2.imread读取的图像有“色差”、“发蓝”问题的解决方法

    使用cv2.imread()读取图像时,默认彩色图像的三通道顺序为B、G、R,这与我们所熟知的RGB中的R通道和B通道正好互换位置了。 而使用plt.imshow()函数却默认显示图像的通道顺序为R、G、B,导致图像出现色差发蓝。 彩色图像出现色差代码: 运行结果如图1-1所示,其颜色偏蓝,怪吓

    2024年02月01日
    浏览(35)
  • 实用技巧:排查数据异常/数据波动问题,该如何下手?

    在我做开发的这些年,让我很头痛的一类问题,不是线上故障,而是数据异常,不知道有没有程序员跟我感同身受。 大多数的服务故障都有较为直观的异常日志,再结合产品表象,相对排查起来还有迹可循,但数据异常的原因就太多了,很多时候连报错日志都没有,排查起来

    2024年04月12日
    浏览(36)
  • Verilog的系统任务----$readmemh和$readmemb

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

    2024年02月07日
    浏览(20)
  • FPGA小技巧之testbench 生成串行和并行数据

    这个5208 如何计算的,因为我们是9600波特率,所以发送1bit的时间为1/9600 秒,如果采用50MHz(周期为20ns)的系统时钟来计数,需要计数的个数为 (1/9600)s / 20ns = 5208 个系统时钟周期 347.2 是根据115200 波特率算出来的,25是 40M的时钟,11 表示11位

    2024年02月07日
    浏览(31)
  • 使用达梦数据库遇到的异常问题

    dm.jdbc.driver.DMException: 数据转换丢失警告 我这里出现问题的SQL语句是: 原因 :是因为list集合中 rz 字段的数据超出的达梦库设置字段类型DEC(7,3)的长度。 dm.jdbc.driver.DMException: 数据未找到 在使用达梦数据库批量插入或更新数据时,给我报了一个从来没有遇到过的错误,当时我

    2024年02月13日
    浏览(33)
  • Oracle-数据库连接数异常上涨问题分析

    问题:         用户的数据库在某个时间段出现连接数异常上涨问题,时间持续5分钟左右,并且问题期间应用无法正常连接请求数据库         从连接数的监控上可以看到数据库平常峰值不到100个连接,在问题时间段突然上涨到400以上 问题分析:         首先查

    2024年02月05日
    浏览(50)
  • STM32硬件IIC卡死问题和DMA发送数据异常问题

    问题1描述: 一直听说STM32的硬件IIC有问题,我平时做项目一直没有遇到过,这次做项目发现硬件IIC居然会自己卡死,现象就是IIC发不出数据,用逻辑分析仪捕捉不到任何电平,必须要重启单片机才能正常,接下来说一下我的硬件环境:STM32作为主机,IIC总线上挂载这AT24C02和一

    2024年02月03日
    浏览(25)
  • 解决pytorch中Dataloader读取数据太慢的问题

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 最近在使用pytorch框架进行模型训练时遇到一个性能问题,即数据读取的速度远远大于GPU训练的速度,导致整个训练流程中有大部分时间都在等待数据发送到GPU,在资源管理器中呈现出CUDA使用率周期性波

    2023年04月11日
    浏览(36)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包