『FPGA通信接口』DDR(3)DDR3颗粒读写测试

news2024/12/26 10:46:03

在这里插入图片描述

文章目录

  • 前言
  • 1.配套工程简介
  • 2.测试内容与策略
  • 3. 测试程序分析
  • 4.程序结果分析
  • 5.一个IP控制两颗DDR3
  • 6.传送门

前言

以四颗MT41K512M16HA-125AIT颗粒为例,介绍如何在一块新制板卡上做关于DDR3的器件测试。前面两篇介绍了什么是DDR,并介绍了xilinx给出的FPGA与DDR完美结合的方案MIG IP核,请按照顺序阅读DDR相关文章,链接在文末。DDR3颗粒,DDR3内存条,DDR4颗粒,DDR4内存条都可以与FPGA相连,DDR芯片选型以及链接形式选型与系统对于数据带宽的要求,存储容量的要求,对结构的要求息息相关,同时不同形式不同代DDR对FPGA选型提出了要求,本文介绍DDR3颗粒与FPGA相连,实现读写测试

1.配套工程简介

提供了两套DDR3颗粒测试工程,工程文件名是DDR3_2PCS800MHz,DDR3_4PCS400MHz,对应2片DDR的800Mhz读写测试,4片DDR的400Hz读写测试。此外还有DDR4颗粒测试工程和DDR3内存条测试工程。两套DDR3颗粒测试工程主控芯片是xilinx xc7k325tffg900-2,颗粒是MT41K512M16HA-125AIT,vivado版本是2020.2。不同的速度测试实际上只需要修改IP里面的配置即可。2片与4片的区别是,一次DDR引脚时钟,写入DDR的数据量是32bit和64bit的区别;MIG IP是按照8倍突发工作,即一个ui_clk用户时钟,MIG读取8个地址的数据,所以2片与4片会导致MIG IP的数据总线是256bit和512bit的区别。为了读者能够快速应用到自己的场景,提供的工程做了区分。需要说明的是,工程应用在本地需要注意,切换相应的时钟输入,切换DDR的UCF文件,切换指示灯的链接,如果有更多的指示灯,则可以接TEST_LENGTH相关的计数器指示一次测试结束,或者指示MIG IP的初始化结果。如果FPGA的型号不同或者DDR颗粒不同,建议重新创建工程进行测试,并且根据对应芯片重新计算TEST_LENGTH。例程都是按照app接口进行控制,在DDR3_4PCS400MHz中提供了一个block design,可以置顶编译综合布线生成bit后,使用tcl的命令便捷读写指定位置,用在定位某个确定位置的读写,这个block design用的是DDR 的AXI接口。
在这里插入图片描述
需要注意,本例的DDR颗粒不在MIG IP所直接支持的列表中,因为通过查询手册自定义了一个DDR型号,如下图所示。
在这里插入图片描述

2.测试内容与策略

通过写入和读出判断读写过程是否正确;此外,工程实践中会遇到当工作频率高的时候DDR读写不稳定, 因此必要进行速度测试。此外还应进行容量进行测试。一个测试工程,对上述三项全部测试;在MIG的平面地址接口中,按照地址顺序写入确定的已知值,然后在按照相同顺序读出这些已知值做比较,相同则常亮led表示测试通过,否则led闪烁表示测试失败。

3. 测试程序分析

附verilog测试代码,省略了模块例化部分,程序步骤解读如下:
①例化clk ip产生200MMIG参考电压输入
②例化MIG ip通过app接口读写ddr数据
③写两段式状态机,为进行容量测试,写至满容量的90%即可。写完切换至读状态,若读写无误则一直读写。Wr_addr_cnt或者rd_addr_cnt每计数一次,app_addr_begin自增8,这是因为,当工作频率配置为800MHz且用户时钟ui_clk与工作频率的比值配置为4:1时,ui_clk为200MHz。四片DDR3的数据位宽为64bit,由于”“DDR(double data rate)”,所以在每一个800MHz周期应该提供128bit数据,因此每一个200MHz周期应该向MIG提供512bit数据。而在单一内核中,每一个平面地址存储位数为16bit,四片即64bit,那512bit/64bit=8,即一个200MHz周期的512bit数据写入了8个平面地址,因此此处一次突发(即Wr_addr_cnt或者rd_addr_cnt每计数一次),app_addr_begin自增8。
该颗粒平面地址空间有16+10+3=29bit,上一段的描述提到一次突发需要8个地址,那么满容量可以进行多少次突发?即2^29(满地址)/8=67108864,将TEST_LENGTH设置为32’d60000000,即写了60000000/67108864=90%的空间,这样可以满足容量测试的要求。
④结合状态机运行状态和MIG返回的指示信号为app接口信号赋值,此处应结合各信号含义和接口时序核准。
⑤用户判错逻辑,写入和读出的都是从0开始递增的数据,当出错时指示灯闪烁。

parameter  TEST_LENGTH = 32'd60000000;
//***********1.先写后读状态机state machine
parameter  IDLE  = 2'd0;           
parameter  WRITE = 2'd1;          
parameter  WAIT  = 2'd2;           
parameter  READ  = 2'd3;   
reg [511:0]my_512_data;
reg [25:0] wr_addr_cnt;
reg [25:0] rd_addr_cnt;
reg [1:0]  state;
always @(posedge ui_clk or negedge rst_n) begin
 if((~rst_n)||(error_flag)) begin 
     state    <= IDLE;          
     my_512_data <= 512'd0;     
     wr_addr_cnt  <= 26'd0;      
     rd_addr_cnt  <= 26'd0;       
     app_addr_begin<= 30'd0;         
 end
 else if(init_calib_complete)begin               //MIG IP核初始化完成
     case(state)
        IDLE:begin
            state    <= WRITE;
            my_512_data <= 512'd0;   
            wr_addr_cnt  <= 26'd0;     
            rd_addr_cnt  <= 26'd0;       
            app_addr_begin     <= 30'd0; 
        end
        WRITE:begin
            if((wr_addr_cnt == TEST_LENGTH-1) &&(app_rdy && app_wdf_rdy))
                state    <= WAIT;                  //写到设定的长度跳到等待状态
            else if(app_rdy && app_wdf_rdy)begin   //写条件满足
                my_512_data <= my_512_data + 1;  //写数据自增
                wr_addr_cnt  <= wr_addr_cnt + 1;   //写计数自增
                app_addr_begin<= app_addr_begin + 8;      //DDR3 地址自增
            end else begin          //写条件不满足,保持当前状态
                 my_512_data <= my_512_data;      
                 wr_addr_cnt  <= wr_addr_cnt;
                 app_addr_begin<= app_addr_begin; 
            end
        end
        WAIT:begin                                                 
            state   <= READ;                     //下一个时钟,跳到读状态
            rd_addr_cnt <= 26'd0;                //读地址复位
            app_addr_begin<= 30'd0;                //DDR3读从地址0
        end
        READ:begin                               //读到设定的地址长度    
            if((rd_addr_cnt == TEST_LENGTH -1 ) && app_rdy)
                state   <= IDLE;                   //则跳到空闲状态 
            else if(app_rdy)begin                  //若MIG已经准备就绪,则开始读
                rd_addr_cnt <= rd_addr_cnt + 1'd1; //用户地址每次加一
                app_addr_begin    <= app_addr_begin + 8;       //DDR3地址加8
            end else begin   //若MIG没准备好,则保持原
                rd_addr_cnt <= rd_addr_cnt;
                app_addr_begin    <= app_addr_begin; 
            end
        end
        default:begin
            state    <= IDLE;
            my_512_data  <= 512'd0;
            wr_addr_cnt  <= 26'd0;
            rd_addr_cnt  <= 26'd0;
            app_addr_begin <= 30'd0;
        end
     endcase
 end
end   
//********2.根据状态机与MIG指示信号为app信号赋值
assign app_en  =((state == WRITE && (app_rdy && app_wdf_rdy))||(state == READ && app_rdy)) ? 1'b1:1'b0;             
assign app_cmd =(state == READ) ? 3'd1 :3'd0;  
assign app_wdf_wren=(state == WRITE && (app_rdy && app_wdf_rdy)) ? 1'b1:1'b0;
assign app_wdf_end =app_wdf_wren; 
assign app_addr    =app_addr_begin;
assign app_wdf_data=my_512_data;   
//****************3.用户判错逻辑
reg     [25:0]   rd_cnt;
wire             rst_n;     //复位,低有效
reg              error_flag;
parameter  L_TIME = 28'd200_000_000;
reg     [27:0]   led_cnt;    //led计数
wire             error;     //读写错误标记
assign rst_n = ~ui_clk_sync_rst;//&&myrst
always @(posedge ui_clk or negedge rst_n) begin
 if(~rst_n) 
    rd_cnt  <= 0;              //若计数到读写长度,且读有效,地址计数器则�?0
 else if(app_rd_data_valid&&(rd_cnt == TEST_LENGTH - 1))
    rd_cnt <= 0;              //其他条件只要读有效,每个时钟自增1
 else if (app_rd_data_valid)
    rd_cnt <= rd_cnt + 1;
end
//判断错误,读出数据应为计数递增数据
assign error = (app_rd_data_valid && (rd_cnt!=app_rd_data));
always @(posedge ui_clk or negedge rst_n) begin
if(~rst_n)
    led2<=0;
else if(rd_cnt==32'd50000000)
    led2<=1;
end 
always @(posedge ui_clk or negedge rst_n) begin
 if(~rst_n) 
     error_flag <= 0;
 else if(error)
     error_flag <= 1;
end
//读写测试正确,指示灯led1常亮,反之则闪烁
always @(posedge ui_clk or negedge rst_n) begin
  if((~rst_n) || (~init_calib_complete )) begin
     led_cnt <= 28'd0;
     led1 <= 1'b0;
 end
 else begin
     if(~error_flag)
         led1 <= 1'b1;
     else begin
         led_cnt <= led_cnt + 28'd1;
         if(led_cnt == L_TIME - 1'b1) begin
         led_cnt <= 25'd0;
         led1 <= ~led1;
         end
    end
end
end

4.程序结果分析

正常结果可以看到与上一节MIG IP给出的时序是一致的。
●写开始时序:
写开始时序
●写结束时序:
写结束时序
●读开始时序:
读开始时序
●读结束时序:
读结束时序
测试的结果最好通过读写一定量并且读写指示灯亮确认。当测试异常时,应按照DDR是否初始化成功、MIG app接口时序是否正确、MIG ip配置是否正确、状态机运行状态是否异常方面入手分析。DDR初始化不成功init_calib_complete为0可能的原因是,时钟输入与MIG IP配置不一致,MIG端口没有正确连接,DDR的UCF约束有问题。

5.一个IP控制两颗DDR3

如下原理图,可以清楚的看到,两颗DDR3的相同的控制线连在了一个控制器的相同引脚,而数据线是各自连的。在PCB布线的时候通常用fly_by的方式连接DDR3。对于FPGA而言,把外部的位宽为16bit的两颗DDR当成了一个位宽为32bit的DDR3来控制。这种往往是为了扩大容量;或者为了匹配rank位宽;或者为了提升带宽,将两片或者四片甚至更多片DDR3放在一起。对于这种场景,只需将上一篇IP配置第5步中的data width设置为实际芯片加起来的位宽即可。如两片16bit位宽颗粒相连,则设置位宽为32bit即可。其余的用户逻辑且把他当作一片位宽为32bit的DDR3即可。实际上,用户存入的32bit数据在实际存放时,高位16bit和低位16bit的数据被放到不同的两片DDR3中,唯一的关联就是,这两个位置的物理值是相等的而已。
在这里插入图片描述

6.传送门

  • 我的主页
  • FPGA通信接口专栏汇总导航
  • 上一篇:MIG IP核的使用
  • DDR3测试工程
END

🔈文章原创,首发于CSDN论坛。
🔈欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🔈欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Java、Android面试]_24_Compose为什么绘制要比XML快?(高频问答)

欢迎查看合集&#xff1a; Java、Android面试高频系列文章合集 本人今年参加了很多面试&#xff0c;也有幸拿到了一些大厂的offer&#xff0c;整理了众多面试资料&#xff0c;后续还会分享众多面试资料。 整理成了面试系列&#xff0c;由于时间有限&#xff0c;每天整理一点&am…

神经网络反向传播算法

今天我们来看一下神经网络中的反向传播算法&#xff0c;之前介绍了梯度下降与正向传播~ 神经网络的反向传播 专栏&#xff1a;&#x1f48e;实战PyTorch&#x1f48e; 反向传播算法&#xff08;Back Propagation&#xff0c;简称BP&#xff09;是一种用于训练神经网络的算…

一键PDF水印添加工具

一键PDF水印添加工具 引言优点1. 精准定位与灵活布局2. 自由旋转与透明度调控3. 精细化页码选择4. 全方位自定义水印内容5. 无缝整合工作流程 功能详解结语工具示意图【工具链接】 引言 PDF作为最常用的文档格式之一&#xff0c;其安全性和版权保护显得尤为重要。今天&#xff…

qcheckbox互斥 也就是单选 纯代码实现 没有ui界面转到槽

1.init&#xff08;&#xff09;函数把所有的qcheckbox找到&#xff0c;然后通过信号与槽&#xff0c;做到点击哪个qcheckbox&#xff0c;哪个qcheckbox就发出信号 2.checkchange&#xff08;&#xff09;槽函数&#xff0c;通过42行拿到是哪个qcheckbox发出的信号&#xff0c…

怎么用微信小程序实现远程控制台球室

怎么用微信小程序实现远程控制台球室呢&#xff1f; 本文描述了使用微信小程序调用HTTP接口&#xff0c;实现控制台球室&#xff0c;控制球台上方的照明灯&#xff0c;单台设备可控制多张球台的照明灯。 可选用产品&#xff1a;可根据实际场景需求&#xff0c;选择对应的规格 …

PVDF-SiO₂复合纳米纤维膜

PVDF-SiO₂复合纳米纤维膜是一种结合了聚偏氟乙烯&#xff08;PVDF&#xff09;和二氧化硅&#xff08;SiO₂&#xff09;纳米粒子的新型复合材料。这种材料通常通过静电纺丝技术或其他纤维制备技术制备而成&#xff0c;具有许多良好的性能和广泛的应用前景。 PVDF是一种热塑性…

中兴UME网管LTE共享参数配置-PLMN添加

本文为中兴设备UME网管电联中频共享参数配置&#xff0c;PLMN添加参数配置部分&#xff0c;因UME与U&#xff13;&#xff11;网管添加PLMN配置区别较大&#xff0c;UME网管需同时配置运营商EN&#xff0d;DC策略&#xff0c;相关配置流程及参数配置如下文。 PLMN eNodeB CU …

《Python编程从入门到实践》day19

#昨日知识点回顾 使用unittest模块测试单元和类 #今日知识点学习 第12章 武装飞船 12.1 规划项目 游戏《外星人入侵》 12.2 安装pygame 终端管理器执行 pip install pygame 12.3 开始游戏项目 12.3.1 创建Pygame窗口及响应用户输入 import sysimport pygameclass…

一个类实现Mybatis的SQL热更新

引言 平时用SpringBootMybatis开发项目&#xff0c;如果项目比较大启动时间很长的话&#xff0c;每次修改Mybatis在Xml中的SQL就需要重启一次。假设项目重启一次需要5分钟&#xff0c;那修改10次SQL就过去了一个小时&#xff0c;成本有点太高了。关键是每次修改完代码之后再重…

【webrtc】MessageHandler 2: 基于线程的消息处理:以PeerConnectionClient为例

PeerConnectionClient 前一篇 nullaudiopoller 并么有场景线程,而是就是在当前线程直接执行的, PeerConnectionClient 作为一个独立的客户端,默认的是主线程。 PeerConnectionClient 同时维护客户端的信令状态,并且通过OnMessage实现MessageHandler 消息处理。 目前只处理一…

CCF-CSP真题题解:201403-1 相反数

201403-1 相反数 #include <iostream> #include <cstring> #include <algorithm> using namespace std;const int MAXN 510;int n, a[MAXN]; int cnt[MAXN];int main() {scanf("%d", &n);for (int i 0; i < n; i) { scanf("%d"…

【分治算法】【Python实现】最接近点对

文章目录 [toc]问题描述一维最接近点对算法Python实现 二维最接近点对算法分治算法时间复杂性Python实现 个人主页&#xff1a;丷从心 系列专栏&#xff1a;分治算法 学习指南&#xff1a;Python学习指南 问题描述 给定平面上 n n n个点&#xff0c;找其中的一对点&#xff…

Python 深度学习(二)

原文&#xff1a;zh.annas-archive.org/md5/98cfb0b9095f1cf64732abfaa40d7b3a 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第五章&#xff1a;图像识别 视觉可以说是人类最重要的感官之一。我们依赖视觉来识别食物&#xff0c;逃离危险&#xff0c;认出朋友和家人…

【C++题解】1044. 找出最经济型的包装箱型号

问题&#xff1a;1044. 找出最经济型的包装箱型号 类型&#xff1a;多分支结构 题目描述&#xff1a; 已知有 A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E 五种包装箱&#xff0c;为了不浪费材料&#xff0c;小于 10 公斤的用 A 型&#xff0c;大于等于 10 公斤小…

浅论汽车研发项目数字化管理之道

随着汽车行业竞争不断加剧&#xff0c;汽车厂商能否快速、高质地推出贴合市场需求的新车型已经成为车企竞争的重要手段&#xff0c;而汽车研发具备流程复杂、专业领域多、协作难度大、质量要求高等特点&#xff0c;企业如果缺少科学健全的项目管理体系&#xff0c;将会在汽车研…

应用监控(Prometheus + Grafana)

可用于应用监控的系统有很多&#xff0c;有的需要埋点(切面)、有的需要配置Agent(字节码增强)。现在使用另外一个监控系统 —— Grafana。 Grafana 监控面板 这套监控主要用到了 SpringBoot Actuator Prometheus Grafana 三个模块组合的起来使用的监控。非常轻量好扩展使用。…

光伏管理系统:降本增效解决方案。

现在是光伏发展的重要节点&#xff0c;如何在众多同行中脱颖而出并且有效的达到降低成本、提高效率也是很多企业都在考虑的问题&#xff0c;鹧鸪云的团队研发出了光伏管理系统&#xff0c;通过更高效、更智能、更全面的管理方式来帮助企业实现降本增效的转型&#xff0c;小编带…

记录AE学习查漏补缺(持续补充中。。。)

记录AE学习查漏补缺 常用win下截图WinShifts导入AI/PS工程文件将图层上移一个位置或者下移一个位置展示/关闭图层标线/标度放大面板适应屏幕大小 CtrlAltF 关键帧熟记关键参数移动锚点位置加选一个关键参数快速回到上下一帧隐藏/显示图层关键帧拉长缩短关键帧按着鼠标左键不松手…

【面试经典 150 | 回溯】单词搜索

文章目录 写在前面Tag题目来源解题思路方法一&#xff1a;回溯 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到的数据结构等内容进行回顾…

Golang | Leetcode Golang题解之第59题螺旋矩阵II

题目&#xff1a; 题解&#xff1a; func generateMatrix(n int) [][]int {matrix : make([][]int, n)for i : range matrix {matrix[i] make([]int, n)}num : 1left, right, top, bottom : 0, n-1, 0, n-1for left < right && top < bottom {for column : lef…