一、需求
项目需要展示FPGA处理后的图像,因此得使用板载的接口接显示器进行显示。此前曾经在ZCU102上用SD卡烧录过Ubuntu桌面系统,并且成功显示。但是,在zynq上编译linux镜像的过程太麻烦,而且经常莫名其妙报错,实在不方便调试。因此尝试使用SDK的example工程进行Standalone的显示驱动调试,初衷就是为了减少工作量。
事后发现,即使用standalone的显示驱动,依然需要踩很多坑。本篇博文将调试的过程详细列举出来,一方面方便以后的复用,另一方面也为其他使用ZCU102的同志提供参考。
二、总览
根据ZCU102板子的资料,板子具备HDMI和Displayport两种硬件接口,分别分布在下图的右边倒数第五个和倒数第三个。
本博文中使用的vivado版本为2019.1。ZCU102的板子版本为rev1.1,由于rev1.1的ZCU102更换了DDR的型号,因此在进行block design的zynq核配置时,必须修改DDR的设置,否则PS端就会罢工。这里放一下正确的DDR配置图,红框中的是修改后的正确参数。(坑点1)
三、调试过程
1.HDMI接口调试
1.1连出信号的方式(不可行)
由于PS内部没有集成HDMI控制器,因此第一个想法是在PL端的block design中接出HDMI的TMDS信号(参考正点原子的DFZU2EG_4EV MPSoC 之嵌入式 VITIS 开发指南),然后将信号通管脚约束绑定到板载HDMI的硬件接口上。通过查阅ug1182,找到了ZCU102的HDMI接口对应的TMDS管脚,如下图所示。然而,将对应的管脚号与PL端信号绑定并进行vivado综合时,一直报错说没有指定管脚电压。
于是,进一步查阅表格发现,这些信号的电压不是传统的LVCMOS33或者LVDS之类,而是备注为U1 MGT,且没有提供具体的电压(I/O standards do not apply),如下图所示。去网上查了一下资料,发现ZCU系列的板子的HDMI口是使用了高速收发器(GTH/GTY)之类的接口标准,该类接口比较复杂,需要专用的IP核处理,无法用一般的信号连出方式进行驱动。因此,放弃了这种连出信号的方式。(坑点2)
1.2通过HDMI 1.4/2.0 Transimitter Subsystem配置的方式(可行但复杂)
既然使用ZCU102的HDMI接口需要专用IP核的配置,那我们就尝试一下。这部分网上有现成的中文配置步骤(https://www.cnblogs.com/xingjian92/p/9871445.html),写的很详细了。这里就不复制粘贴了,简单总结下需要注意的点。
HDMI 1.4/2.0 Transimitter Subsystem是一个收费IP,需要去Xilinx官网申请一个120天免费的License,绑定Vivado所在电脑的IP地址,然后将License导入到vivado中才能使用。下图所示是配置好License后,License Manager中会出现三个HDMI核相关的许可。需要注意的是,这三个IP对应的Host IDs Match这一栏必须是yes才能用。如果是no的话,虽然也可以调用HDMI的IP核,但是综合的时候会报错(坑点3)。出现no的原因是你在申请License的时候绑定错了电脑的IP地址,需要进入Xilinx官网里面重新配置(坑点4)。另外,刚配置好建议重启下电脑,否则vivado很可能在导出比特流时报错(坑点5)。
其他的坑点应该没有了,根据 (https://www.cnblogs.com/xingjian92/p/9871445.html)中的步骤(Tx only),配置好vivado中的block design,综合、实现、导出比特流、打开SDK、导入示例工程、下载都很顺利。我们的显示器成功显示彩条,表示HDMI验证通过,这里就不放实物演示图了。
虽然这种方式可以实现HDMI的显示,然而缺点较多。下图是官方HDMI例程顶层block design,里面主要的是v_hdmi_tx_ss IP核,还包括如audio、PHY等多个辅助IP核。要想将该工程移植到自己的工程中,首先得考虑把audio核去掉,这一步我们根据网上的公开资料实现成功。其次需要搞清楚整体逻辑,需要去通读pg235。另外,像video_frame_cc这种辅助的IP核,官方是没有介绍文档的,进一步加剧了开发难度。考虑到我们的需求仅仅需要实现显示功能,并不需要高速视频传输要求,不能花太多时间去死磕这一套开发流程。还有,终极硬伤是HDMI整套工程仅有120天的免费期。因此这条路就从入门到放弃了。希望以后有走通了将这套工程移植到自己项目中的同志,可以写出博客分享出来。
2.Displayport接口调试
在评估了ZCU102的HDMI接口使用难度过大后,我们将希望寄托于Displayport接口上。Displayport有两种使用方式。第一是使用PL端的IP核去驱动,如下图所示。这种方式和上面的HDMI核开发方式类似,估计也是适用于高速视频传输场景的,需要一个完整子系统去支撑,因此我们没有验证,直接放弃这条路。第二是使用ZYNQ核内部集成的PS端DP控制器。由于网上没有搜索到针对ZCU102 PS端DP接口的中文参考资料,因此以下我们将详细介绍该方式的配置步骤。
1.1 vivado中zynq核的配置
①创建新工程,在block design中创建zynq ultra核,运行block automation配置。
②双击zynq ultra核,首先对DDR configuration按本博文开头的说明进行修改。
③在I/O Configuration页面,使能Display port控制器,注意,Lane Selection选择Dual Lower(坑点6)。事实上,按照ZCU102的auto系统配置,该选项默认选项是Dual Higher。我一度选择使用默认的Dual Higher或Single Lower,后续都无法进行正常显示,更换Vivado版本、更换显示器也不work,浪费了很长时间。这里为何要选择Dual Lower的具体原因尚不清楚,可能跟板子自身以及SDK中的驱动程序有关。期间也查阅了Xilinx论坛大量的相关讨论,大多数仅涉及SDK中驱动程序参数的修改而没有提到ZYNQ核中Lane Selection的参数修改,大坑啊!最终启发我的是Xilinx论坛中的一个问答,这里贴出网址(AMD Customer Community)。提问的老哥尝试了多种配置都不成功,最终通过下载Xilinx官方提供的针对ZCU102的base TRD工程,并且严格对照了的TRD工程中的zynq核进行设置后才成功。我也下载了TRD工程,确认了TRD工程中Lane Selection确实选择的是Dual Lower。
④Clock Configuration的Input Clock页面,无需修改,按照默认配置即可,如下图所示。
⑤Clock Configuration的Output Clock页面,无需修改,按照默认配置即可,如下图所示。
以上就是zynq核中所有有关DP接口的参数配置。配置好后按一般的开发步骤,validation design、create HDL wrapper、synthesis、implementation、generate bitstream。
1.2 SDK中驱动程序的配置
生成好比特流后,导出比特流,打开SDK进行配置,具体步骤如下。
①与一般SDK程序开发步骤相同,首先在File->New中选择生成板级支持包,生成的板级支持包如下图所示。
②进入板级支持包中的system.mss文件,选择modify this BSP's Settings选项。
③在driver中将psu_dp的Driver更换为dppsu。
④在systm.mss页面中,找到psu_dpdma这一栏,选择import examples。选择xdpdma_video_example,点击ok。
⑤此时,SDK左边出现了到处的example工程,打开src目录中的xdpma_video_example.c程序。
⑥修改xdpma_video_example.c程序。可以修改的地方包括两大部分。第一部分是演示程序生成的图像分辨率,如下图所示,需要根据使用的显示器分辨率进行调整,一般使用默认的1920*1080*4或3840*2160*4。
⑦修改的第二部分是控制器的参数,在InitRunConfig函数中,如下图所示。请注意,这里主要需要调整两项参数。第一是VideoMode项,需要与刚才第六步中设置的分辨率进行统一。此处我们设置的是XVIDC_VM_1920*1080_60_P这个宏定义,其中1920*1080表示分辨率,后面的60指频率(坑点7)。第二是LinkRate项,宏定义中有三种可选,分别是162BPS、270BPS、5430BPS(坑点8)。上述两个参数的设置很坑,不同的显示器设置都不一样,需要进行大量尝试。一般是固定分辨率后,调整频率和LinkRate参数的排列组合,然后连接板子运行看有没有显示。
⑧确定上述两个参数后,就可以进行烧录和验证了。如果正确配置,串口打印的信息如下。
显示器正确显示的实物演示如下,上半部分是黑条,下半部分是绿条。
⑨其他坑点之转接线问题
建议做这个实验时使用带DP接口的显示器,直接使用DP线连接板子和显示器。如果手头上没有带DP接口的显示器,可以购买DP转HDMI的转接线(不推荐)(坑点8)。然而,市面上的DP转HDMI线都很难适配本工程。按照熊猫君的说法(关于Xilinx ZYNQ Ultrascale+ MPSoC使用原生PS端DP接口实现Live模式输出的经验分享 - 知乎),最好去店里去一个一个试,或者买绿联4K/60Hz的主动式转接线(本人也买了这条线,亲测可用)。
⑩显示器的选择问题(坑点9)
建议先试自己的显示器是否可用。如果不可用,从Xilinx官方测试通过的显示器中选购(Zynq UltraScale+ MPSoC Base TRD 2018.3 - Xilinx Wiki - Confluence)
本人在自己的两台显示器都测试成功,型号及对应配置供参考:
(1)Redmi A22。这个显示器没有DP接口,使用了刚才提到的绿联转接线。SDK中设置的控制器参数为XVIDC_VM_1920x1080_60_P,LINK_RATE_162GBPS。
(2)ViewSonic VX2758-4K-PRO。因为当时错误的配置,导致第一台显示器无法显示,当时认为是显示器的问题,所以根据Xilinx给的兼容显示器列表,买了这一台,自带DP接口。SDK中设置的控制器参数为XVIDC_VM_3840x2160_30_P,LINK_RATE_540GBPS。