当前位置: 首页 > news >正文

PL端DDR3读写(1)

1、范围

       前面让团队小伙伴仿照米联客教程测试了一下,后面似乎读写有时候有误码,后期小伙伴离职,这个事情就不了了之。最近工作又需要对PL端DDR3进行读写,于是亲自对这一部分进行详细测试论证。该文档用来描述如何读写PL端DDR3、形成统一的接口模块,最后在实际板卡中对DDR3进行功能及性能验证测试。

2、基本概念

2.1、DDR3

       目前主流的DDR有DDR3、DDR4和DDR5,DDR属于SDRAM一类的数据存储器,它是一种同步动态存储器,断点数据会丢失。DDR是Double Date Rate的英文缩写,后面数值表示第几代,例如DDR3表示第三代DDR,数值越高表示性能越好。市面上常用的DDR3来自美光的MT41K系列,在贸泽上搜索价格在二十多元。找到美光手册,如下:

可以看到有三个型号,分别为MT41K1G4、MT41K512M8、MT41K256M16,三种型号的容量均为4Gb。4、8和16表示数据线位宽,1G、512M和256M由bank地址、行地址和列地址位宽共同决定,具体如下所示:

同样的数据容量不同的后缀代表不同的速率。

​​​​​​​2.2、硬件设计

       DDR3供电电压一般为1.5V,如果是在PS端接入DDR3,则固定接在BANK502端,需要将管脚一一对应。例如PYNQ中接入的DDR3连接如下所示:

       如果想用两块DDR3扩展出1GB容量,将BANK502高16位的数据线接在另外一块DDR中,DM和DQS接在2、3接口,其他连线两块DDR共接。 当PL端接入DDR3时,需要注意DDR管脚连接关系,应尽量用MIG IP推荐的连接管脚。

3、FPGA设计

       本设计实现的功能为基于MIG 完成对DDR3读写操作,最后对读写数据进行校验。DDR3读写有两种工作方式:FIFO模式和RAM模式。在FIFO模式,DDR3可以理解为超大的FIFO,当没有写数据时,禁止读数据。例如当写入10个字节数据,在读取10个数据以后,再读数据时,输出数据内容为0,并将空标志拉高。在RAM模式时,可以允许反复读数据。例如当写入10个数据时,当读取10个数据以后,再读取第11个数据时,将重复读取第1个数据。

​​​​​​​3.1、管脚约束

DDR的管脚约束为DDR3.ucf文件,具体将原理图与文件内容进行一一对应就行。

​​​​​​​​​​​​​​3.2、IP配置

在工程中增加MIG IP,具体步骤如下所示:

a) 选择IP

时钟选择为800MHz,根据板卡硬件选择DDR型号,由于有两片拼接,所以位宽选择为32。

选择系统时钟和参考时钟为no buffer,选中DCI cache

点击Read XDC/UCF,选择前面修改的约束文件,点击Validate,就可以选择Next。

b) 例化IP

mig_7series_0模块对外接口,时钟关系如下图所示,本部分参考其他博客:

如上图,包含了四个时钟:

1)系统时钟,即MIG核工作时钟,通常命名sys_clk;

2)参考时钟,即MIG核参考时钟,通常命名ref_clk,必须是200MHz;

3)DDR芯片工作时钟,由FPGA输出给DDR的差分时钟,可以命名ddr_clk;

4)用户时钟,MIG核输出给用户端的时钟,通常命名ui_clk。

注意1:ddr_clk与ui_clk有比例关系,ddr_clk:ui_clk = 4:1或2:1,当ddr_clk=800MHz时,只能是4:1。

注意2:用户数据位宽如何计算,例如ddr_clk=800MHz时,ui_clk = 200MHz,ddr物理位宽为16bit(2片ddr菊花链连接就是32bit),上下沿采集(2倍),因此用户数据位宽=800*32*2/200=256bit。

注意3:256bit/32bit=8,所以ddr用户地址每次加8。

注意4:app地址位宽:

ADDR_WIDTH = RANK_WIDTH + BANK_WIDTH + ROW_WIDTH + COL_WIDTH

通过UG586可知RANK_WIDTH默认为1,查看DDR手册可以知道BANK_WIDTH3ROW_WIDTH15COL_WIDTH10,所以app_addr位宽为29。

序号

信号名称

位宽

方向

说明

1

ddr3_dq

32

IO

与DDR连接

2

ddr3_dqs_n

4

IO

3

ddr3_dqs_p

4

IO

4

ddr3_addr

15

O

5

ddr3_ba

3

O

6

ddr3_ras_n

1

O

7

ddr3_cas_n

1

O

8

ddr3_we_n

1

O

9

ddr3_reset_n

1

O

10

ddr3_ck_p

1

O

11

ddr3_ck_n

1

O

12

ddr3_cke

1

O

13

ddr3_cs_n

1

O

14

ddr3_dm

4

O

15

ddr3_odt

1

O

16

sys_clk_i

1

I

系统时钟,频率为200MHz

17

clk_ref_i

1

I

参考时钟,频率为200MHz

18

app_addr

29

I

地址输入

19

app_cmd

3

I

读写控制命令0:写 1:读

20

app_en

1

I

命令写入使能,高有效

21

app_wdf_data

256

I

写数据

22

app_wdf_end

1

I

突发写最后一个时钟

23

app_wdf_mask 

32

I

写数据掩码

24

app_wdf_rdy

1

O

DDR准备完成,高有效

25

app_rd_data

256

O

读数据

26

app_rd_data_end

1

O

突发读最后一个时钟

27

app_rd_data_valid

1

O

读数据有效

28

app_rdy

1

O

读写接收准备完成,高有效

29

app_sr_req     

1

I

保留位

30

app_ref_req    

1

I

刷新请求

31

app_zq_req     

1

I

ZQ校准请求

32

app_sr_active  

1

O

保留位

33

app_ref_ack    

1

O

刷新响应

34

app_zq_ack     

1

O

ZQ校准响应

35

ui_clk

1

O

用户时钟

36

ui_clk_sync_rst

1

O

复位,高电平

37

init_calib_complete

1

O

IP初始化完成标志,高电平有效

38

device_temp

12

O

39

sys_rst

1

I

低电平复位

​​​​​​​3.3、时序与流程
a) 命令操作时序

       当用户逻辑app_en信号被断言且app_rdy信号从MIG被断言时,MIG接受命令。每当app_rdy被取消断言时,MIG将忽略该命令。用户逻辑需要将app_en与有效命令和地址值沿着保持为高电平,直到app_rdy被断言,如下图所示:

只有当app_rdy 与 app_en同时为高时,命令和地址才会被写入到MIG,如图红色的位置,这类似于AXI里的握手信号。

b) 写数据

         首先需要检查app_wdf_rdy,该信号为高表明此时IP核数据接收处于准备状态,可以接收用户发过来的数据,在当前时钟拉高写使能(app_wdf_wren),同时给出写数据这样加上发起的写命令操作就可以成功向IP核写数据,具体时序如下图所示:

如上图所示,写数据有三种情形均可以正确写入:

  1. 写数据时序和写命令时序发生在同一拍
  2. 写数据时序比写命令时序提前一拍
  3. 写数据时序比写命令时序至多延迟两拍
c)读数据

       用户发出读命令后,用户只需等待数据有效信号(app_rd_data_valid)拉高,为高表明此时数据总线上的数据是有效的返回数据,有效读数据要晚若干周期才出现在数据总线上。如下图所示:

至此已经完成vivado中DDR的配置和相关基础知识的了解。后续需要自己根据app信号的时序关系,编写对应的控制信号。网络上有很多,但是似乎直接能用的并不多。下一文档详细编写如何编写app控制时序。同时ug586似乎在xilinx官网无法下载,这里将ucf文件和ug586上传到CSDN,可以免费下载:https://download.csdn.net/download/weixin_39813867/91008302

http://www.xdnf.cn/news/1038421.html

相关文章:

  • 转换专家从格式转换到创意剪辑的全链路解决方案
  • AIGC 基础篇 Python基础(练习1)
  • 板凳-------Mysql cookbook学习 (十--6)
  • Python6.14打卡(day46)
  • StampedLock入门教程
  • 面试问题总结——关于C++(四)
  • 【卫星通信】3GPP标准提案:面向NB-IoT(GEO)场景的IMS信令优化方案-降低卫星通信场景下的语音呼叫建立时延
  • ELK日志文件分析系统——L(Logstash)
  • Flutter 状态管理与 API 调用的完美结合:从理论到实践
  • python实战:使用Python合并PDF文件
  • pyqt5,python开发软件,文件目录如何设置,如何引用,软件架构如何设计
  • 洛谷 P5711:闰年判断
  • 基于Python学习《Head First设计模式》第十一章 代理模式
  • 「Linux中Shell命令」Shell常见命令
  • Vue 3 砸金蛋互动抽奖游戏
  • Redis事务与驱动的学习(一)
  • 出现端口占用,关闭端口进程命令
  • Redis三种集群概述:主从复制、哨兵模式与Cluster模式
  • MySQL 究极奥义·动态乾坤大挪移·无敌行列转换术
  • SSH参数优化与内网穿透技术融合:打造高效远程访问解决方案
  • Android 获取签名 keystore 的 SHA1和MD5值
  • transactional-update原子性更新常用命令
  • 数据库期末
  • LangChain开发智能问答(RAG)系统实战教程:从零构建知识驱动型AI助手
  • 推荐一个轻量级跨平台打包工具 PakePlus:重塑前端项目桌面化体验
  • 微软云注册被阻止怎么解决?
  • uniapp 腾讯地图服务
  • 【DSP笔记 · 第3章】数字世界的“棱镜”:离散傅里叶变换(DFT)完全解析
  • 自定义 eslint 规则
  • 基于Java开发的浏览器自动化Playwright-MCP服务器