介绍如何简单使用vivado的ddr4。
本文是基于生成好之后的rocket chip RTL代码,在这个基础上挂上vivado的ddr4 IP。目标板是VCU118。
生成好的RTL接口是:
- clock,计划是50M
- reset,高电平有效
- axi4 master, 数据位宽64
- uart,波特率230400
Block Design
为了更方便的连接各IP,本次采用block design的方式,来连接Soc。步骤如下:
新建project
create block design
右键,选择add module
选择DVRocketSystem,这样就把rocket作为一个module加进了block design里面
再右键,add ip,添加DDR4(MIG)
customize IP。board页面,选择clock为default 250mhz clk1,选择ddr4 sdram c1,选择复位为reset。
basic页面,把axi4接口勾上,其他基本默认就好,因为已经和板子做了关联了。比如memory part,比如clocking就1200MHz,PHY to controller clock frequency ratio为4:1,意味着axi4总线的时钟为300MHz
AXI option。数据位宽为512。
advanced clocking。额外输出的了一个100MHz时钟。
其他配置不需要改变,然后生成就行了。到此,生成了一个DDR4的PHY和controller,PHY时钟1200M,controller的接口是axi4的,数据位宽512,时钟频率300M。入口时钟default 250M,reset为系统复位。
对照rocket的design,有几个问题需要关注。
- 时钟和复位怎么安排
- axi数据位宽不一致
- axi时钟域不一致
时钟
为了解决时钟和数据位宽问题,采用如下结构。
DDR出来的100M给到一个clk_wiz,分频到50M,送给rocket。
rocket出来的axi width64送给一个AXI dwidth converter,转到width512,然后再经过AXI clock converter转到300M时钟,送给DDR。
其中clk_wiz_0的配置如下。
其中AXI dwidth converter配置如下。
其中AXI clk converter配置如下。
复位
为了解决复位问题,采用如下结构。使用了3个proc_sys_reset。
DDR出来的complete信号送给proc_sys_reset_2的lock端,等到DDR初始化之后,再送出reset信号给后级模块,因为这里还是100M,所以再经过一个clk_wiz,转到50M,再接一个proc_sys_reset_0,得到同源的时钟复位。
另外一个proc_sys_reset_1是给300M时钟域的reset,给DDR和AXI clk converter模块使用。
最后,把系统复位接到3个proc_sys_reset。
其中3个proc_sys_reset的配置如下。
生成的代码如下,需要注意下信号的高低有效。
diagram
最终出来的结构图如下。