使用VDMA驱动HDMI显示

使用VDMA驱动HDMI显示#

实验Vivado工程为“vdma_hdmi_out”。

PS没有集成显示控制系统,需要借助PL来实现,实现的方案有很多,但是都离不开DMA系统,DMA系统可以完成显示数据从ddr3读出到显示器的显示,降低CPU的开销,VDMA是xilinx开发的特殊DMA,专门用于视频输入输出,是学习xilinx FPGA视频处理的重要内容。

前面的HDMI显示数据是PL内部产生的,这个实验中显示数据是PS生成的,然后PL通过VDMA送给HDMI接口。

Vivado工程建立#

由于VDMA显示是一个非常重要的内容,本实验会详细介绍Vivado的搭建过程。

  1. 新建一个名为“vdma_hdmi_out”工程。

../_images/image139.png
  1. 创建一个Block设计

../_images/image226.png
  1. 设计名称保持默认不变

../_images/image326.png
  1. 添加ZYNQ处理器

../_images/image418.png
  1. 配置ZYNQ参数,使能HP0接口,用于VDMA快速读取ddr。

../_images/image512.png
  1. 配置Bnak电平标准,Bank0为LVCMOS 3.3V,Bank1 为 LVCMOS 1.8V,使能串口

../_images/image610.png
  1. 使能I2C0,并且选择EMIO,这样可以把I2C连接到PL端。

../_images/image710.png
  1. 配置时钟,FCLK_CLK0配置为100Mhz,FCLK_CLK1配置为142Mhz,这个时钟用于VDMA读取数据。

../_images/image810.png
  1. 配置ddr3,选择MT41256M16 RE-125

../_images/image910.png
  1. 配置中断,使能IRQ_F2P,接收PL端的中断

../_images/image1010.png
  1. 添加VDMA IP

../_images/image1115.png
  1. 按照下图配置VDMA基本参数

../_images/image1212.png
  1. 配置VDMA高级参数

../_images/image1310.png
  1. 添加视频时序控制器

../_images/image149.png
  1. 配置视频时序控制器参数

../_images/image159.png
  1. 添加AXI流转视频输出控制器

../_images/image168.png
  1. 配置AXI流转视频输出控制器参数

../_images/image178.png
  1. 由于视频有很多分辨率,各种分辨的时钟频率不相同,需要使用一个动态时钟控制器,这个IP来自开源软件,找到例程里的repo目录,复制到自己的目录下

../_images/image188.png
  1. 添加IP仓库

../_images/image198.png
  1. 添加完成以后可以看到很多IP

../_images/image205.png
  1. 添加动态时钟控制器

../_images/image2111.png
  1. 添加一个GPIO,用于HDMI模块复位

../_images/image227.png
  1. 配置GPIO参数

../_images/image236.png
  1. 连接Vivado可能无法自动连接的时钟信号

../_images/image245.png
  1. 连接其他一些关键信号

../_images/image255.png ../_images/image255.png
  1. 连接中断信号,需要先添加一个Concat IP,用于信号连接

../_images/image265.png ../_images/image275.png
  1. 使用Vivado自动连接功能,完成剩下的线连接

../_images/image285.png
  1. 选择所有模块自动连接

../_images/image295.png
  1. 运行“Run Block Automation”完成一些必要的端口导出

../_images/image305.png
  1. 展开vid_io_out端口

../_images/image3111.png
  1. 选择我们需要的端口导出

../_images/image327.png
  1. 导出IIC_0端口

../_images/image336.png
  1. 导出视频时钟端口

../_images/image345.png
  1. 名称修改为hdmi_out_clk

../_images/image355.png
  1. 修改其他端口的名称

../_images/image364.png
  1. 保存设计后按F6 检查设计,没有问题后创建HDL文件

../_images/image374.png
  1. 添加HDMI输出的xdc文件,约束管脚

../_images/image384.png
  1. xdc文件内容如下

set_property PACKAGE_PIN G16 [get_ports hdmi_out_clk]
set_property PACKAGE_PIN H22 [get_ports {hdmi_out_data[0]}]
set_property PACKAGE_PIN G22 [get_ports {hdmi_out_data[1]}]
set_property PACKAGE_PIN G17 [get_ports {hdmi_out_data[2]}]
set_property PACKAGE_PIN F17 [get_ports {hdmi_out_data[3]}]
set_property PACKAGE_PIN G15 [get_ports {hdmi_out_data[4]}]
set_property PACKAGE_PIN D15 [get_ports {hdmi_out_data[5]}]
set_property PACKAGE_PIN E15 [get_ports {hdmi_out_data[6]}]
set_property PACKAGE_PIN F18 [get_ports {hdmi_out_data[7]}]
set_property PACKAGE_PIN E18 [get_ports {hdmi_out_data[8]}]
set_property PACKAGE_PIN H17 [get_ports {hdmi_out_data[9]}]
set_property PACKAGE_PIN H18 [get_ports {hdmi_out_data[10]}]
set_property PACKAGE_PIN H19 [get_ports {hdmi_out_data[11]}]
set_property PACKAGE_PIN H20 [get_ports {hdmi_out_data[12]}]
set_property PACKAGE_PIN G19 [get_ports {hdmi_out_data[13]}]
set_property PACKAGE_PIN F19 [get_ports {hdmi_out_data[14]}]
set_property PACKAGE_PIN G20 [get_ports {hdmi_out_data[15]}]
set_property PACKAGE_PIN G21 [get_ports {hdmi_out_data[16]}]
set_property PACKAGE_PIN F21 [get_ports {hdmi_out_data[17]}]
set_property PACKAGE_PIN F22 [get_ports {hdmi_out_data[18]}]
set_property PACKAGE_PIN E21 [get_ports {hdmi_out_data[19]}]
set_property PACKAGE_PIN D21 [get_ports {hdmi_out_data[20]}]
set_property PACKAGE_PIN D22 [get_ports {hdmi_out_data[21]}]
set_property PACKAGE_PIN C22 [get_ports {hdmi_out_data[22]}]
set_property PACKAGE_PIN B21 [get_ports {hdmi_out_data[23]}]
set_property PACKAGE_PIN E20 [get_ports hdmi_out_de]
set_property PACKAGE_PIN E19 [get_ports hdmi_out_hs]
set_property PACKAGE_PIN C17 [get_ports {hdmi_rstn_tri_o[0]}]
set_property PACKAGE_PIN F16 [get_ports hdmi_out_vs]
set_property PACKAGE_PIN B22 [get_ports hdmi_i2c_scl_io]
set_property PACKAGE_PIN A22 [get_ports hdmi_i2c_sda_io]

set_property IOSTANDARD LVCMOS33 [get_ports hdmi_i2c_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_i2c_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_out_clk]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_out_de]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_out_hs]
set_property IOSTANDARD LVCMOS33 [get_ports {hdmi_out_data[*]}]
set_property IOSTANDARD LVCMOS33 [get_ports hdmi_out_vs]
set_property IOSTANDARD LVCMOS33  [get_ports {hdmi_rstn_tri_o[0]}]

set_property SLEW FAST [get_ports {hdmi_out_data[*]}]
set_property DRIVE 8 [get_ports {hdmi_out_data[*]}]
set_property SLEW FAST [get_ports hdmi_out_clk]
set_property SLEW FAST [get_ports hdmi_out_de]
set_property SLEW FAST [get_ports hdmi_out_hs]
set_property SLEW FAST [get_ports hdmi_out_vs]
  1. 编译生成bit文件

Vitis软件编写调试#

  1. 导出硬件

../_images/image394.png ../_images/image403.png
  1. 运行Vitis,新建一个名为vdma_hdmi的APP,已经预备了相关程序

../_images/image419.png
  1. 由于程序文件较多,不再具体介绍,直接复制例程的源代码。删除src目录下的文件,使用例程的src目录文件代替

../_images/image424.png
  1. 在Vitis下按F5刷新

  2. 在display_ctrl文件夹中,diplay_ctrl.c主要是显示的控制,vga_mode.h中加入了一些显示分辨率的时序参数。

../_images/image434.png

在display_ctrl.c中,可以修改displayPtr->vMode,改变显示的分辨率。

../_images/image442.png
  1. Dynclk文件中,主要功能是根据不同的分辨率配置锁相环的时钟输出,产生像素时钟。

../_images/image452.png
  1. 连接HDMI输出端口到显示器,编译运行

../_images/image462.png
  1. 显示器显示出一幅图片

../_images/image47.jpeg