使用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/image150.png
  1. 创建一个Block设计

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

set_property PACKAGE_PIN H1 [get_ports hdmi_out_clk]
set_property PACKAGE_PIN G3 [get_ports {hdmi_out_data[0]}]
set_property PACKAGE_PIN H3 [get_ports {hdmi_out_data[1]}]
set_property PACKAGE_PIN H4 [get_ports {hdmi_out_data[2]}]
set_property PACKAGE_PIN G7 [get_ports {hdmi_out_data[3]}]
set_property PACKAGE_PIN G8 [get_ports {hdmi_out_data[4]}]
set_property PACKAGE_PIN G1 [get_ports {hdmi_out_data[5]}]
set_property PACKAGE_PIN H5 [get_ports {hdmi_out_data[6]}]
set_property PACKAGE_PIN H6 [get_ports {hdmi_out_data[7]}]
set_property PACKAGE_PIN G4 [get_ports {hdmi_out_data[8]}]
set_property PACKAGE_PIN F4 [get_ports {hdmi_out_data[9]}]
set_property PACKAGE_PIN F5 [get_ports {hdmi_out_data[10]}]
set_property PACKAGE_PIN E5 [get_ports {hdmi_out_data[11]}]
set_property PACKAGE_PIN G6 [get_ports {hdmi_out_data[12]}]
set_property PACKAGE_PIN F6 [get_ports {hdmi_out_data[13]}]
set_property PACKAGE_PIN E7 [get_ports {hdmi_out_data[14]}]
set_property PACKAGE_PIN F7 [get_ports {hdmi_out_data[15]}]
set_property PACKAGE_PIN D3 [get_ports {hdmi_out_data[16]}]
set_property PACKAGE_PIN C3 [get_ports {hdmi_out_data[17]}]
set_property PACKAGE_PIN C4 [get_ports {hdmi_out_data[18]}]
set_property PACKAGE_PIN D5 [get_ports {hdmi_out_data[19]}]
set_property PACKAGE_PIN C5 [get_ports {hdmi_out_data[20]}]
set_property PACKAGE_PIN C6 [get_ports {hdmi_out_data[21]}]
set_property PACKAGE_PIN E8 [get_ports {hdmi_out_data[22]}]
set_property PACKAGE_PIN D8 [get_ports {hdmi_out_data[23]}]
set_property PACKAGE_PIN G2 [get_ports hdmi_out_de]
set_property PACKAGE_PIN E4 [get_ports hdmi_out_hs]
set_property PACKAGE_PIN L4 [get_ports {hdmi_rstn_tri_o[0]}]
set_property PACKAGE_PIN E3 [get_ports hdmi_out_vs]
set_property PACKAGE_PIN J8 [get_ports hdmi_i2c_scl_io]
set_property PACKAGE_PIN K8 [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/image404.png
  1. 运行Vitis,新建一个名为vdma_hdmi的APP,已经预备了相关程序

../_images/image4110.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/image451.png
  1. 连接HDMI输出端口到显示器,编译运行

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

../_images/image47.jpeg