第三章 VDMA基础:架构、寄存器与回环测试
各位同学,今天我们来聊聊VDMA。说实话,VDMA是图像加速里最基础也最关键的模块之一。我刚开始接触Xilinx的VDMA时,也被那一堆寄存器搞得头大。但后来发现,只要理解了它的核心架构,配置起来其实就那么几件事。
3.1 VDMA架构:它到底在干什么?
VDMA,全称Video Direct Memory Access。说白了,就是专门为视频流设计的高速DMA。它跟普通DMA最大的区别是什么?普通DMA搬完一块数据就停了,VDMA可以一直搬、循环搬、同步搬。
我画了一张架构图,你看一眼就明白了:
VDMA内部有三个关键部分:
- AXI4主接口:负责跟DDR内存打交道,读写帧数据
- AXI4-Stream接口:跟你的视频处理逻辑对接,数据流式进出
- 寄存器控制模块:通过AXI4-Lite配置,决定怎么搬、搬多少、同步方式
嗯,这里要注意:VDMA其实有两个数据通道——读通道和写通道。你可以只用一个,也可以两个都用。回环测试时,我们两个都用。
3.2 寄存器配置:别怕,就这几个关键寄存器
VDMA的寄存器有几十个,但实际项目中常用的不超过10个。我列个表给你看:
| 偏移地址 | 寄存器名称 | 功能描述 | 我常用的值 |
|---|---|---|---|
| 0x00 | VDMA_CR | 控制寄存器,启动/停止、复位 | 0x00000003 |
| 0x04 | VDMA_SR | 状态寄存器,查错误、查忙闲 | 只读 |
| 0x0C | VDMA_PARK | 帧同步模式选择 | 0x00000000 |
| 0x30 | VDMA_VSIZE | 垂直尺寸(行数) | 0x00000438 (1080p) |
| 0x34 | VDMA_HSIZE | 水平尺寸(每行字节数) | 0x00002800 (1920*4) |
| 0x38 | VDMA_FRMDLY_STRIDE | 行跨度(Stride) | 0x00002800 |
| 0xAC | VDMA_START_ADDR_1 | 帧缓冲区起始地址 | 0x10000000 |
配置顺序我建议这样:先配帧尺寸和跨度,再配地址,最后启动。为什么?因为VDMA在启动时会立即检查这些参数,顺序错了它可能罢工。
3.3 同步模式:三种模式怎么选?
VDMA有三种同步模式,我直接说人话:
- 自动同步模式(Auto Sync):VDMA自己管帧同步,你只管发数据。适合简单的图像传输。
- 动态同步模式(Dynamic Sync):通过外部信号控制帧切换。适合需要精确帧控制的场景。
- 非同步模式(Non-Sync):VDMA不管帧边界,一直搬数据。适合连续流。
我个人习惯用自动同步模式做回环测试。为什么?省事。你想想看,回环测试的目的是验证通路,不是验证同步逻辑。自动模式下,VDMA内部会处理好帧切换,你只需要关注数据对不对。
3.4 实战:VDMA回环测试
好了,理论说完了,咱们直接上手。回环测试的思路很简单:
- VDMA从DDR读一帧数据 → 送到输出Stream
- 输入Stream接收数据 → 写回DDR的另一块区域
- 比较两块区域的数据,看是否一致
我曾经在一个项目中用这个方法来验证VDMA的配置是否正确。那次板子刚上电,图像全是雪花,我一度以为是硬件坏了。后来用回环测试一跑,发现是Stride配错了——图像宽度和行跨度不一致,导致数据错位。
下面是一个简单的配置代码示例(C语言风格):
// 1. 复位VDMA
Xil_Out32(VDMA_BASE + 0x00, 0x00000004); // 复位
usleep(100);
Xil_Out32(VDMA_BASE + 0x00, 0x00000000); // 释放复位
// 2. 配置帧参数(1920x1080, RGB888)
Xil_Out32(VDMA_BASE + 0x34, 0x00001E00); // HSIZE = 7680字节
Xil_Out32(VDMA_BASE + 0x38, 0x00001E00); // STRIDE = 7680
Xil_Out32(VDMA_BASE + 0x30, 0x00000438); // VSIZE = 1080行
// 3. 设置帧缓冲区地址
Xil_Out32(VDMA_BASE + 0xAC, 0x10000000); // 读帧地址
Xil_Out32(VDMA_BASE + 0xB0, 0x20000000); // 写帧地址
// 4. 启动VDMA(自动同步模式)
Xil_Out32(VDMA_BASE + 0x00, 0x00000003); // 同时启动读写通道
跑完回环测试后,怎么判断结果?两个方法:
- 软件比对:用CPU把两块内存的数据读出来,逐字节比较。慢但可靠。
- 硬件校验:在FPGA里加一个CRC校验模块,实时比较。快但需要额外逻辑。
我个人偏好先用软件比对做一次全面检查,确认没问题后,再用硬件校验做在线监控。这样既保证了正确性,又不影响性能。
3.5 避坑指南
最后,分享几个我踩过的坑:
- Stride必须对齐:AXI总线要求地址对齐到64字节。如果Stride不是64的倍数,VDMA会报错。我曾经因为Stride设成7679(少1字节),折腾了一下午。
- 帧缓冲区大小要够:一帧的大小 = VSIZE * STRIDE。如果分配的内存不够,VDMA会写到别人的地盘上,后果嘛...系统崩溃。
- 时钟域问题:VDMA的AXI4接口和Stream接口可以在不同时钟域。但如果你两个时钟频率差太多,建议加FIFO做异步处理。
好了,VDMA的基础就讲到这里。回环测试是验证VDMA配置最直接的方法,建议你在每个新板子上都跑一遍。下一节我们会讲VDMA的中断处理和性能优化,到时候再聊。
可可精品资料库