一、ddr 控制ip的代码介绍

1.ddr IP(DFI)
根据上述示意图,大家可以看到PH1A的ddr IP包含了uart和一个ddr,但是我们今天的实验的重点是如何使用这个ddr控制IP,所以不涉及他自带的这个uart,而是外接了一个自己写的uart。
接着,我们可以看到ddr ip后面连接DDR 控制器,DFI 接口是连接 DDR 控制器和 DDR PHY(物理层)之间的接口。这个接口负责处理控制器与内部存储器之间的底层通信,确保数据在存储器和控制器之间的可靠传输。

2.ddr控制器(APP)
DDR 控制器连接了应用层的DDR接口和内部的DFI接口。右侧为DDR物理芯片接口,负责产生具体的操作时序,并直接操作芯片管脚。这一侧用户只负责分配正确的管脚,其他不用关心。用户只需操作MIG IP的用APP接口就能进行DDR数据的读写。

3.APP-AXI
我们的样例是通过FDMA对ddr进行读写,但是FDMA使用的是AXI接口,ddr控制器使用APP接口,那我们就需要将APP接口转换成AXI接口,这就是我们这个模块的作用。
4.uiFDMA AXI控制器
uiFDMA,这是一个AXI控制器IP,所以如果想要控制好ddr,就需要学会控制这个AXI控制器IP 那我们先来看一下这个FDMA的时序
FDMA 的写时序

fdma_wready 设置为 1,当 fdma_wbusy=0 的时候代表 FDMA 的总线非忙,可以进行一次新的 FDMA 传输,这 个时候可以设置 fdma_wreq=1,同时设置 fdma burst 的起始地址和 fdma_wsize 本次需要传输的数据大小(以 bytes 为 单位)。当 fdma_wvalid=1 的时候需要给出有效的数据,写入 AXI 总线。当最后一个数写完后,fdma_wvalid 和 fdma_wbusy 变为 0。
FDMA 的读时序

fdma_rready 设置为 1,当 fdma_rbusy=0 的时候代表 FDMA 的总线非忙,可以进行一次新的 FDMA 传输,这个时候可以设置fdma_rreq=1,同时设置fdma burst的起始地址和fdma_rsize本次需要传输的数据大小(以bytes为单位)。当 fdma_rvalid=1的时候需要给出有效的数据,写入 AXI 总线。当最后一个数写完后,fdma_rvalid 和 fdma_rbusy变为 0。
二、uart Loop 实验原理
这样我们就算结束了对ddr控制器IP的介绍,接下来我们进行这个uart loop的实验。我们这个实验的总体逻辑呢是这样的,我们先利用PC发一个串口数据给uart,当uart收到数据之后呢,将这个po_flag进行拉高,当po_flag拉高时,我们进行一个data的寄存,同时也将FDMA的写请求进行一个拉高,当valid拉高时,我们将寄存的data的值写入FDMA,在此期间WBUSY是为1的,当data写完时,busy为0,我们在此下降沿将读请求拉高,就完成了这个loop。

这里需要注意的有两点:
这里涉及到一个FDMA和uart的大小端转换

FDMA的请求都需要两拍,但是我们的po_flag只有一拍,我这里是利用寄存器完成了这个转换。

最后呢在需要说明的一点是关于uart的时钟和波特率,这部分根据需要自己手动调整。

三、uart Loop 实验现象
现在我们把bit文件下载进去,打开串口助手,进行测试。

四、总结
利用本文代码控制ddr读写的核心问题在于,如何控制FDMA(本文实验实际没有对ddr进行配置),所以透彻理解FDMA的读写时序是非常重要的!!!!