[X]关闭

[米联客-XILINX-H3_CZ08_7100] FPGA_PL-DDR篇连载-08 fdma数据通路加入sobel算法ip

文档创建者:FPGA课程
浏览次数:288
最后更新:2024-09-10
文档课程分类-AMD-ZYNQ
AMD-ZYNQ: ZYNQ-FPGA部分 » 2_FPGA实验篇(仅旗舰) » 2-FPGA PL DDR使用
本帖最后由 FPGA课程 于 2024-9-10 09:37 编辑

​ 软件版本:VIVADO2021.1
操作系统:WIN10 64bit
硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA
实验平台:米联客-MLK-H3-CZ08-7100开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!



1概述
本文实验目的:
1:掌握2个uifdma_dbuf IP的同时使用,以及读写通道之间的同步设计
2:实现1路数据实时显示,1路数据实时sobel计算通过uifdma_dbuf+fdma3.2保持到内存中。
3:掌握uifdma_dbuf IP stride参数的设置,实现一个屏幕实时显示当前摄像头视频以及实时计算的sobel视频
4:掌握图像处理中多通道读写的多缓存机制
2系统框图
本系统中通过milianke uifdma_dbuf ip的写通道将摄像头采集到的数据通过AXI intercomment 写入DDR3,同时使用milianke uifdma_dbuf ip的读通道读取DDR3中的视频数据通过HDMI接口输出至显示屏。
为2个输入图像在一个显示器输出,而不出现撕裂,关键就是在于uifdmadbuf的同步机制,这里让uifdmadbuf1的wbuf_sync_o作为同步信号,分别给uifdmadbuf1的读和写通道,以及uifdmadbuf2的写通道使用。uifdmadbuf2的读通道没有使用。
将其中一路数据进行soble计算,为了完成sobel计算,RGB565 to RGB888输出的de信号不是连续的,需要通过uirgbfifo转换成连续的de信号。
f4a29425c5b24bdca9852ec9c46a688b.jpg
3硬件电路分析
1:FEP扩展接口
摄像头扩展卡安装在 FEP 上,在硬件的 PCB 上有丝印标注。下图为H3 底板的 FEP 连接器定义。
f49db15cf9e44e6ba256bb12651c08a4.jpg
FEP-BASE 扩展卡有 3.3V 和 1.8V 版本,3.3V 的定义如下,其中 OE 控制了子卡是上电使能:
4eebdac1f0b04e74a0182e35a8b971d9.jpg
FEP-BASE 扩展卡有 3.3V 和 1.8V 版本,1.8V 的定义如下,其中 OE 控制了子卡是上电使能:
a302dcfcd2c94aedb973f9cfa6447bc9.jpg
HDMI底板原理图如下。
751637d2df384c5f83f767399b26acee.jpg

2.fpga_pin.xdc摄像头和HDMI输出IO约束
以下约束如果和原理图或者配套源码不相符的,以原理图和配套工程中约束为准,以下约束时使用 FEP-BASE-3V3 版本的定义,如果时1V8 版本的,需要修改开发板的跳线帽,以及修改card1_power_en的pin 脚约束
  1. create_clock -period 10.000 -name sysclk -add [get_ports sysclk_p]
  2. set_property PACKAGE_PIN D9 [get_ports sysclk_p]
  3. set_property IOSTANDARD DIFF_SSTL135 [get_ports sysclk_p]

  4. create_clock -period 10.000 -name cmos1_pclk_i -add [get_ports I_cmos1_pclk]

  5. set_property PACKAGE_PIN AC28 [get_ports card1_power_en]
  6. set_property IOSTANDARD LVCMOS33 [get_ports card1_power_en]
  7. #---------------------------sensor---------------------------
  8. set_property PACKAGE_PIN AE28 [get_ports I_cmos1_pclk]
  9. set_property PACKAGE_PIN AJ26 [get_ports I_cmos1_vsync]
  10. set_property PACKAGE_PIN AK26 [get_ports I_cmos1_href]
  11. set_property PACKAGE_PIN AF28 [get_ports O_cmos1_xclk]
  12. set_property PACKAGE_PIN AH29 [get_ports {cmos1_data_i[0]}]
  13. set_property PACKAGE_PIN AH28 [get_ports {cmos1_data_i[1]}]
  14. set_property PACKAGE_PIN AJ29 [get_ports {cmos1_data_i[2]}]
  15. set_property PACKAGE_PIN AJ28 [get_ports {cmos1_data_i[3]}]
  16. set_property PACKAGE_PIN AK30 [get_ports {cmos1_data_i[4]}]
  17. set_property PACKAGE_PIN AJ30 [get_ports {cmos1_data_i[5]}]
  18. set_property PACKAGE_PIN AH27 [get_ports {cmos1_data_i[6]}]
  19. set_property PACKAGE_PIN AH26 [get_ports {cmos1_data_i[7]}]
  20. set_property PACKAGE_PIN AK27 [get_ports cmos1_scl]
  21. set_property PACKAGE_PIN AK28 [get_ports cmos1_sda]

  22. set_property IOSTANDARD LVCMOS18 [get_ports I_cmos1_vsync]
  23. set_property IOSTANDARD LVCMOS18 [get_ports I_cmos1_href]
  24. set_property IOSTANDARD LVCMOS18 [get_ports I_cmos1_pclk]
  25. set_property IOSTANDARD LVCMOS18 [get_ports O_cmos1_xclk]
  26. set_property IOSTANDARD LVCMOS18 [get_ports {cmos1_data_i[*]}]
  27. set_property IOSTANDARD LVCMOS18 [get_ports cmos1_scl]
  28. set_property IOSTANDARD LVCMOS18 [get_ports cmos1_sda]
  29. set_property PULLUP true [get_ports cmos1_scl]
  30. set_property PULLUP true [get_ports cmos1_sda]

  31. set_property PACKAGE_PIN U26 [get_ports HDMI_TX_CLK_P]
  32. set_property PACKAGE_PIN W29 [get_ports {HDMI_TX_P[0]}]
  33. set_property PACKAGE_PIN T24 [get_ports {HDMI_TX_P[1]}]
  34. set_property PACKAGE_PIN R27 [get_ports {HDMI_TX_P[2]}]

  35. set_property IOSTANDARD TMDS_33 [get_ports HDMI_TX_CLK_P]
  36. set_property IOSTANDARD TMDS_33 [get_ports {HDMI_TX_P[2]}]
  37. set_property IOSTANDARD TMDS_33 [get_ports {HDMI_TX_P[1]}]
  38. set_property IOSTANDARD TMDS_33 [get_ports {HDMI_TX_P[0]}]

  39. set_property DCI_CASCADE {33 35} [get_iobanks 34]

  40. set_property BITSTREAM.GENERAL.COMPRESS true [current_design]

  41. set_clock_groups -asynchronous -group [get_clocks -of_objects [get_pins system_i/clk_wiz_0/inst/mmcm_adv_inst/CLKOUT0]] -group [get_clocks -of_objects [get_pins system_i/clk_wiz_0/inst/mmcm_adv_inst/CLKOUT1]] -group [get_clocks -of_objects [get_pins system_i/clk_wiz_0/inst/mmcm_adv_inst/CLKOUT2]] -group [get_clocks *I_cmos1_pclk*]
  42. set_false_path -from [get_pins system_i/uivtc_0/inst/vtc_vs_o_reg/C]
复制代码
4基于图像化的逻辑设计
09004e9b25ae4396a0f9188163af2b7a.jpg
1:帧同步设计
对于多路视频传输的场合,需要正确设置同步。 uifdma_dbuf0的写通道输出帧同步计数器直接接入
uifdma_dbuf0,uifdma_dbuf1的写通道同步计数输入。uifdma_dbuf0的读通道,延迟1帧于uifdma_dbuf0的写通道帧计数器。
98bc93d68381440ea74dd9121019d3b4.jpg

2:多路视频的同屏显示原理
cb07118fcdb740ebb1263c871d3d3469.jpg
以把2个摄像头CAM0和CAM1输出到同一个显示器上为列,为了把2个图像显示到1个显示器,首先得搞清楚以下关系:
hsize:每1行图像实际在内存中占用的有效空间,以32bit表示一个像素的时候占用内存大小为hsize*4
hstride:用于设置每行图像第一个像素的地址,以32bit 表示一个像素的时候v_cnt* hstride*4
vsize:有效的行

因此很容易得出cam0的每行第一个像素的地址也是v_cnt* hstride*4
同理如果我们需要把cam1在hsize和vsize空间的任何位置显示,我们只要关心cam1每一行图像第一个像素的地址,可以用以下公式v_cnt* hstride*4+offset

这里2个通道的640*480分辨率视频,在同一个1280*720的视频输出显示。VIDEO1没有进行soble计算的原始图像在左上角,VIDEO2是计算后的图像在右下角。
a944470626584bd3adf8bf4f1399bed2.jpg
uifdma_dbuf支持stride参数设置,stride参数可以设置输入数据X(hsize)方向每一行数据的第一个像素到下一个起始像素的间隔地址,利用stride参数可以非常方便地摆放输入视频到内存中的排列方式。
VIDEO1的start addr1=0x10000000(第一个图像的起始地址对于PL DDR可以从0地址开始,低于PS DDR建议偏移20MB)
VIDEO2的start addr1=0x10000000+(640-480)*1280*4+(1280-640)*4
下面重点看下uifdma_dbuf的设置。
3:uifdma_dbuf_0的配置
2f65d98950634c1d9987cd3026584198.jpg
4:uifdma_dbuf_1的配置
e55b3c03034940dd99c3cc429293583d.jpg
这里是把摄像头的输出分辨率设置为640*480,并且把相同的摄像头数据分别输入到uifdma_dbuf0和uifdma_dbuf1的写通道。输出到显示器的分辨率为1280*720
5:地址空间分配
80c1aeb2df394dcdb7f91a5c6ce72c44.jpg
5硬件连接
bfed49db6db74037bc6553cb5b712b42.jpg
6实验结果
f327da1d04b743119e0b7f360f9a5237.jpg





您需要登录后才可以回帖 登录 | 立即注册

本版积分规则