【ALINX 实战笔记】FPGA 大神 Adam Taylor 使用 ChipScope 调试 AMD Versal 设计

news2025/5/19 17:11:25

本篇文章来自 FPGA 大神、Ardiuvo & Hackster.IO 知名博主 Adam Taylor。在这里感谢 Adam Taylor 对 ALINX 产品的关注与使用。为了让文章更易阅读,我们在原文的基础上作了一些灵活的调整。原文链接已贴在文章底部,欢迎大家在评论区友好互动。

在上篇文章中,我们已经通过测试图案生成器,成功验证了 ALINX VD100 的图像显示链路。

这次终于要接入 MIPI 摄像头,进行真正的图像处理了!

在这个过程中,集成逻辑分析仪(ILA)将作为我们的调试“透视眼”,帮助我们逐步验证每一阶段的运行效果。

本项目规模不小,从图像采集到处理再到输出,每一环都可能出现问题——做好调试准备了吗?

那就让我们开始吧!

项目工具清单

本次开发平台基于 AMD Versal AI Edge 芯片,开发板采用 ALINX 的 VD100。

Versal AI Edge 系列是 AMD 推出的系统级异构芯片(SoC),专为边缘端 AI 应用优化,集成了 Arm Cortex-A72 应用处理器、Cortex-R5F 实时处理器、可编程逻辑(PL)以及 AI 引擎专用加速模块等多种处理单元。这些模块通过片上网络(NoC)实现高效互联,形成强大灵活的计算平台,非常适合本地化部署卷积神经网络(CNN)等 AI 推理任务。

ALINX VD100 开发板配备了 2 个 4 通道的 MIPI 摄像头输入接口,以及一个 LVDS LCD 显示输出,并且支持 Vivado免费版开发环境,对原型验证和早期开发者极其友好。

在进入 AI 阶段前,我们需要打好基础——构建一条稳定的图像处理通路。基本流程如下:

1. 图像采集(MIPI 摄像头)

2. 预处理(去马赛克、颜色空间转换、图像增强)

3. 缓存存储(VDMA + DDR)

4. 图像显示(LVDS LCD 输出)

一个可靠的图像通路必须满足三个条件:

1. 摄像头正常采集

2. 数据通路不丢包

3. 显示输出无错帧

通过早期验证这些关键环节,可确保 I/O 分配、时钟策略和图像处理流程的正确性,降低在集成上层 AI 逻辑或应用功能时的开发风险。只有基础打牢,后续的开发迭代才能更高效,项目推进也更有把握。

Versal 调试机制

虽然 Versal 器件的应用调试与 7 系列、UltraScale 及 UltraScale+ 系列大体相似(均可使用 ChipScope 工具),但在使用方式上也发生了一些变化:

_

旧平台(7/US/US+等)

Versal 平台

Debug hub

连接方式

通过 JTAG 接口

通过 CIPS 中的 

AXI4 接口

Debug hub

插入方式

自动插入

自动/手动 

(涉及 DFX 必须手动)

Debug Core

接口协议

专有接口

标准 AXI4-Stream

AXI-Stream ILA 特性

集成标准ILA+System ILA

支持 BRAM/URAM存储介质选择

标准 ILA 与

System ILA 分立

存储介质固定

Versal 的调试架构更加现代化,也更加灵活,但也意味着你在设计之初就必须考虑调试资源的布局,尤其是 CIPS 模块和 AXI 调试路径 的预留。

调试方法论

FPGA 开发是一个需要多次迭代的过程,只有遵循逻辑推理的方法,才能更高效地解决问题,不至于造成资源浪费。我在调试时遵循以下原则帮助我更快速地排查问题:

1. 问题拆解:将复杂问题拆解为更小的部分

2. 控制变量:减少变量与干扰项

3. 假设验证:做出合理预测,并验证预测结果

4. 前瞻规划:在设计初期就规划好调试方案与观测点位置

ILA 插桩策略

集成逻辑分析仪(ILA)使用起来非常占用逻辑和 BRAM 资源,且采样深度、监控信号的宽度也会直接影响 BRAM 的使用量——探针越宽、采样窗口越长,占用的内存越多,资源也越快耗尽。

在真实项目中使用 ILA 进行调试时,必须合理选择插桩位置,以平衡调试可视性与 FPGA 资源的使用。我的建议是,在遵循前述调试方法论的条件下:

1. 优先监控控制信号、复位线、状态/错误标志等关键位置。这些信号通常可以第一时间反映系统行为,帮助我们在调试早期就定位问题。

2. 逐步拓展至一些关键的 AXI 总线,尤其是连接 Versal 的片上网络(NoC)与处理系统(PS)的部分,这些接口是可编程逻辑(PL)、NoC 与 PS 之间的数据主通道,能揭示系统集成与数据传输过程中的一些微妙问题。

因此,在调试初期,我们可以从一组合理的控制信号、复位、状态/错误信息以及关键 AXI 接口信号入手,采用中等采样深度

这样既能获得系统层面的良好可视性,又能为后续迭代调试保留资源空间。

Vivado 设计架构

基于 Versal AI Edge 的图像处理流水线,核心架构通过 CIPS 模块实现全局控制;图像帧通过一系列 IP 模块被采集与处理;应用程序、DDR 内存访问以及 CIPS 与可编程逻辑(PL)之间的通信,通过片上网络(NoC)实现高速互联。

系统的整体结构如下图所示:

具体使用的 IP 核取决于应用需求,但核心流水线一般包括:传感器接口、去马赛克(Demosaic)、颜色空间转换、图像增强、视频时序控制模块,以及 AXI Stream 的互联与控制逻辑。

ILA 模块

ILA_LCD_LVDS

→ 监控 LCD / LVDS 接口,观察状态与错误信号。

Video ILA

→ 使用四个通道,监控图像处理流程中的 AXI-Stream 视频信号,包括 MIPI 原始输出、去马赛克后的 RGB 流、24 位像素转换输出与 VDMA 输出流。

Memory ILA

→ 监控通过 NoC 访问 DDR 的 AXI4 总线,确保 DDR 的读写操作正常进行。

Output ILA

→ 监控 AXI-Stream 到视频输出的状态信息,如视频输出同步信号诊断(HSync/VSync 相位对齐监测)  

IP 模块

CIPS

→ 配置处理系统(PS)、平台初始化,提供外设访问。

NoC

→ 提供高带宽的数据流通通道,连接多个互联节点,并集成 DDR 控制器用于外部内存访问。

SmartConnect

→ 连接各 IP 模块的 AXI-Lite 寄存器接口,使处理系统可以对其进行控制与配置。

MIPI CSI-2 RX

→ 支持 4 通道,每通道 1000 Mbps 的高速图像采集。

Demosaic(去马赛克)

→ 将图像传感器输出的 Bayer 模式像素数据转换为完整 RGB 图像,重建每个像素的颜色信息。

AXI Subset Converter

→ 将 40 位像素数据(每个 RGB 通道 10 位)转换为 24 位格式(每通道 8 位),每时钟周期保持 4 像素吞吐。

VDMA

→ 桥接 AXI4-Stream 与 AXI4 存储接口,在 NoC 上实现 DDR 帧存的存取,同时为处理阶段提供高效的缓存机制。

AXI4-Stream to Video Out

→ 将 AXI4-Stream 视频流转换为标准视频输出格式,生成 HSync、VSync 等同步信号以驱动显示设备。

VTC

→ 生成 HSync、VSync、有效视频等信号,并与AXI4-Stream to Video Out模块同步,确保显示时序正确。

LCD LVDS 接口

→ 将标准并行视频输出信号转换为串行 VESA LVDS 格式,适配基于 LVDS 的 LCD 显示屏。

Advanced IO Wizard

→ 配置 Versal 设备中的 XPIO,将 LVDS 输出数据串行化,满足 VESA LVDS 显示标准。

通过这些 ILA,我们能够同时观察静态的状态信号与动态的高带宽数据流,全面掌控图像处理系统的运行状态。

完整设计如图所示,可通过本项目所附的 TCL 脚本复现该设计。

在生成比特流时,必须定义 XDC I/O 约束文件,明确所有外部接口的物理引脚位置与电气标准。

关键接口的引脚配置如下:

set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property DIFF_TERM_ADV TERM_100 [get_ports sys_clk_p]
set_property PACKAGE_PIN A23 [get_ports {clkout1_p[0]}]
set_property IOSTANDARD LVDS15 [get_ports {clkout1_p[0]}]
set_property PACKAGE_PIN F22 [get_ports {dataout1_p_0[0]}]
set_property PACKAGE_PIN A20 [get_ports {dataout1_p_1[0]}]
set_property PACKAGE_PIN C22 [get_ports {dataout1_p_2[0]}]
set_property PACKAGE_PIN A25 [get_ports {dataout1_p_3[0]}]
set_property IOSTANDARD LVDS15 [get_ports {dataout1_p_*[0]}]
set_property PACKAGE_PIN E24 [get_ports {lcd_en}]
set_property IOSTANDARD LVCMOS15 [get_ports {lcd_en}]
set_property PACKAGE_PIN D24 [get_ports {lcd_sync}]
set_property IOSTANDARD LVCMOS15 [get_ports {lcd_sync}]
set_property PACKAGE_PIN AC11 [get_ports {DDR4_act_n[0]}]
set_property PACKAGE_PIN AB12 [get_ports {DDR4_adr[0]}]
set_property PACKAGE_PIN AB17 [get_ports {DDR4_adr[10]}]
set_property PACKAGE_PIN AE13 [get_ports {DDR4_adr[11]}]
set_property PACKAGE_PIN AH12 [get_ports {DDR4_adr[12]}]
set_property PACKAGE_PIN AD15 [get_ports {DDR4_adr[13]}]
set_property PACKAGE_PIN AD21 [get_ports {DDR4_adr[14]}]
set_property PACKAGE_PIN AD17 [get_ports {DDR4_adr[15]}]
set_property PACKAGE_PIN AC13 [get_ports {DDR4_adr[16]}]
set_property PACKAGE_PIN AE22 [get_ports {DDR4_adr[1]}]
set_property PACKAGE_PIN AD22 [get_ports {DDR4_adr[2]}]
set_property PACKAGE_PIN AB15 [get_ports {DDR4_adr[3]}]
set_property PACKAGE_PIN AD12 [get_ports {DDR4_adr[4]}]
set_property PACKAGE_PIN AE17 [get_ports {DDR4_adr[5]}]
set_property PACKAGE_PIN AD16 [get_ports {DDR4_adr[6]}]
set_property PACKAGE_PIN AG11 [get_ports {DDR4_adr[7]}]
set_property PACKAGE_PIN AE14 [get_ports {DDR4_adr[8]}]
set_property PACKAGE_PIN AB14 [get_ports {DDR4_adr[9]}]
set_property PACKAGE_PIN AC16 [get_ports {DDR4_ba[0]}]
set_property PACKAGE_PIN AD11 [get_ports {DDR4_ba[1]}]
set_property PACKAGE_PIN AB18 [get_ports {DDR4_bg[0]}]
set_property PACKAGE_PIN AC19 [get_ports {DDR4_ck_t[0]}]
set_property PACKAGE_PIN AD19 [get_ports {DDR4_ck_c[0]}]
set_property PACKAGE_PIN AB21 [get_ports {DDR4_cke[0]}]
set_property PACKAGE_PIN AC17 [get_ports {DDR4_cs_n[0]}]
set_property PACKAGE_PIN AG12 [get_ports {DDR4_dm_n[0]}]
set_property PACKAGE_PIN AH13 [get_ports {DDR4_dm_n[1]}]
set_property PACKAGE_PIN AE28 [get_ports {DDR4_dm_n[2]}]
set_property PACKAGE_PIN AD24 [get_ports {DDR4_dm_n[3]}]
set_property PACKAGE_PIN V22 [get_ports {DDR4_dm_n[4]}]
set_property PACKAGE_PIN V28 [get_ports {DDR4_dm_n[5]}]
set_property PACKAGE_PIN N28 [get_ports {DDR4_dm_n[6]}]
set_property PACKAGE_PIN U25 [get_ports {DDR4_dm_n[7]}]
set_property PACKAGE_PIN AF14 [get_ports {DDR4_dq[0]}]
set_property PACKAGE_PIN AH18 [get_ports {DDR4_dq[10]}]
set_property PACKAGE_PIN AH20 [get_ports {DDR4_dq[11]}]
set_property PACKAGE_PIN AH14 [get_ports {DDR4_dq[12]}]
set_property PACKAGE_PIN AH22 [get_ports {DDR4_dq[13]}]
set_property PACKAGE_PIN AH15 [get_ports {DDR4_dq[14]}]
set_property PACKAGE_PIN AG22 [get_ports {DDR4_dq[15]}]
set_property PACKAGE_PIN AF26 [get_ports {DDR4_dq[16]}]
set_property PACKAGE_PIN AE26 [get_ports {DDR4_dq[17]}]
set_property PACKAGE_PIN AH27 [get_ports {DDR4_dq[18]}]
set_property PACKAGE_PIN AE27 [get_ports {DDR4_dq[19]}]
set_property PACKAGE_PIN AG18 [get_ports {DDR4_dq[1]}]
set_property PACKAGE_PIN AG27 [get_ports {DDR4_dq[20]}]
set_property PACKAGE_PIN AD26 [get_ports {DDR4_dq[21]}]
set_property PACKAGE_PIN AG26 [get_ports {DDR4_dq[22]}]
set_property PACKAGE_PIN AG28 [get_ports {DDR4_dq[23]}]
set_property PACKAGE_PIN AE24 [get_ports {DDR4_dq[24]}]
set_property PACKAGE_PIN AD25 [get_ports {DDR4_dq[25]}]
set_property PACKAGE_PIN AH24 [get_ports {DDR4_dq[26]}]
set_property PACKAGE_PIN AF25 [get_ports {DDR4_dq[27]}]
set_property PACKAGE_PIN AG23 [get_ports {DDR4_dq[28]}]
set_property PACKAGE_PIN AG25 [get_ports {DDR4_dq[29]}]
set_property PACKAGE_PIN AG15 [get_ports {DDR4_dq[2]}]
set_property PACKAGE_PIN AH23 [get_ports {DDR4_dq[30]}]
set_property PACKAGE_PIN AH25 [get_ports {DDR4_dq[31]}]
set_property PACKAGE_PIN Y22 [get_ports {DDR4_dq[32]}]
set_property PACKAGE_PIN V23 [get_ports {DDR4_dq[33]}]
set_property PACKAGE_PIN Y23 [get_ports {DDR4_dq[34]}]
set_property PACKAGE_PIN W24 [get_ports {DDR4_dq[35]}]
set_property PACKAGE_PIN AA22 [get_ports {DDR4_dq[36]}]
set_property PACKAGE_PIN V24 [get_ports {DDR4_dq[37]}]
set_property PACKAGE_PIN AA21 [get_ports {DDR4_dq[38]}]
set_property PACKAGE_PIN W25 [get_ports {DDR4_dq[39]}]
set_property PACKAGE_PIN AF18 [get_ports {DDR4_dq[3]}]
set_property PACKAGE_PIN V25 [get_ports {DDR4_dq[40]}]
set_property PACKAGE_PIN W27 [get_ports {DDR4_dq[41]}]
set_property PACKAGE_PIN AA28 [get_ports {DDR4_dq[42]}]
set_property PACKAGE_PIN W26 [get_ports {DDR4_dq[43]}]
set_property PACKAGE_PIN Y26 [get_ports {DDR4_dq[44]}]
set_property PACKAGE_PIN AA26 [get_ports {DDR4_dq[45]}]
set_property PACKAGE_PIN AB28 [get_ports {DDR4_dq[46]}]
set_property PACKAGE_PIN AB26 [get_ports {DDR4_dq[47]}]
set_property PACKAGE_PIN P27 [get_ports {DDR4_dq[48]}]
set_property PACKAGE_PIN K27 [get_ports {DDR4_dq[49]}]
set_property PACKAGE_PIN AF13 [get_ports {DDR4_dq[4]}]
set_property PACKAGE_PIN R28 [get_ports {DDR4_dq[50]}]
set_property PACKAGE_PIN L28 [get_ports {DDR4_dq[51]}]
set_property PACKAGE_PIN R27 [get_ports {DDR4_dq[52]}]
set_property PACKAGE_PIN K28 [get_ports {DDR4_dq[53]}]
set_property PACKAGE_PIN T28 [get_ports {DDR4_dq[54]}]
set_property PACKAGE_PIN M27 [get_ports {DDR4_dq[55]}]
set_property PACKAGE_PIN P25 [get_ports {DDR4_dq[56]}]
set_property PACKAGE_PIN L26 [get_ports {DDR4_dq[57]}]
set_property PACKAGE_PIN R26 [get_ports {DDR4_dq[58]}]
set_property PACKAGE_PIN M26 [get_ports {DDR4_dq[59]}]
set_property PACKAGE_PIN AF19 [get_ports {DDR4_dq[5]}]
set_property PACKAGE_PIN T25 [get_ports {DDR4_dq[60]}]
set_property PACKAGE_PIN K26 [get_ports {DDR4_dq[61]}]
set_property PACKAGE_PIN T26 [get_ports {DDR4_dq[62]}]
set_property PACKAGE_PIN J25 [get_ports {DDR4_dq[63]}]
set_property PACKAGE_PIN AG13 [get_ports {DDR4_dq[6]}]
set_property PACKAGE_PIN AE19 [get_ports {DDR4_dq[7]}]
set_property PACKAGE_PIN AH17 [get_ports {DDR4_dq[8]}]
set_property PACKAGE_PIN AG21 [get_ports {DDR4_dq[9]}]
set_property PACKAGE_PIN AG17 [get_ports {DDR4_dqs_t[0]}]
set_property PACKAGE_PIN AG16 [get_ports {DDR4_dqs_c[0]}]
set_property PACKAGE_PIN AG20 [get_ports {DDR4_dqs_t[1]}]
set_property PACKAGE_PIN AH19 [get_ports {DDR4_dqs_c[1]}]
set_property PACKAGE_PIN AC28 [get_ports {DDR4_dqs_t[2]}]
set_property PACKAGE_PIN AD27 [get_ports {DDR4_dqs_c[2]}]
set_property PACKAGE_PIN AF24 [get_ports {DDR4_dqs_t[3]}]
set_property PACKAGE_PIN AF23 [get_ports {DDR4_dqs_c[3]}]
set_property PACKAGE_PIN Y24 [get_ports {DDR4_dqs_t[4]}]
set_property PACKAGE_PIN AA23 [get_ports {DDR4_dqs_c[4]}]
set_property PACKAGE_PIN Y28 [get_ports {DDR4_dqs_t[5]}]
set_property PACKAGE_PIN Y27 [get_ports {DDR4_dqs_c[5]}]
set_property PACKAGE_PIN U27 [get_ports {DDR4_dqs_t[6]}]
set_property PACKAGE_PIN U28 [get_ports {DDR4_dqs_c[6]}]
set_property PACKAGE_PIN P26 [get_ports {DDR4_dqs_t[7]}]
set_property PACKAGE_PIN N27 [get_ports {DDR4_dqs_c[7]}]
set_property PACKAGE_PIN AC22 [get_ports {DDR4_odt[0]}]
set_property PACKAGE_PIN AC24 [get_ports {DDR4_reset_n[0]}]
set_property PACKAGE_PIN AB23 [get_ports {sys_clk_clk_p[0]}]
set_property PACKAGE_PIN AC23 [get_ports {sys_clk_clk_n[0]}]
set_property IOSTANDARD LVDS15 [get_ports {sys_clk_clk_n[0]}]
set_property IOSTANDARD LVDS15 [get_ports {sys_clk_clk_p[0]}]
create_clock -period 5.000 -name sys_clk -waveform {0.000 2.500} [get_ports {sys_clk_clk_p[0]}]
set_property PACKAGE_PIN G26 [get_ports {cam1_gpio[0]}]
set_property IOSTANDARD LVCMOS15 [get_ports {cam1_gpio[0]}]
set_property PULLUP true [get_ports {cam1_gpio[0]}]
set_property PACKAGE_PIN G27  [get_ports cam1_i2c_scl_io]
set_property PACKAGE_PIN F28 [get_ports cam1_i2c_sda_io]
set_property IOSTANDARD LVCMOS15 [get_ports cam1_i2c_scl_io]
set_property IOSTANDARD LVCMOS15 [get_ports cam1_i2c_sda_io]
set_property PULLUP true [get_ports cam1_i2c_scl_io]
set_property PULLUP true [get_ports cam1_i2c_sda_io]
set_property PACKAGE_PIN U23 [get_ports mipi_phy_if_0_clk_p]
set_property PACKAGE_PIN T23 [get_ports mipi_phy_if_0_data_p[0]]
set_property PACKAGE_PIN R23 [get_ports mipi_phy_if_0_data_p[1]]
set_property PACKAGE_PIN L23 [get_ports mipi_phy_if_0_data_p[2]]
set_property PACKAGE_PIN M22 [get_ports mipi_phy_if_0_data_p[3]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_clk_p]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_clk_n]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_p[0]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_n[0]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_p[1]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_n[1]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_p[2]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_n[2]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_p[3]]
set_property IOSTANDARD MIPI_DPHY [get_ports mipi_phy_if_0_data_n[3]]
set_property CLOCK_REGION X3Y0 [get_cells -hier -filter {name =~ *mipi_csi2_rx_subsyst_1/inst/phy/inst/inst/rxbyteclkhs_buf}]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets -hier -filter {name =~ *mipi_csi2_rx_subsyst_0/inst/phy/inst/inst/*/inst/BANK_WRAPPER_INST0/fifo_wr_clk[0]}]

应用软件配置

应用软件将基于 Vitis 统一软件平台进行开发,负责执行以下关键任务:

  • 配置摄像头(借助 ALINX 提供的初始化文件)。

  • 配置视频时序控制器(VTC),输出 720p 所需的同步信号。

  • 配置 Demosaic IP,实现正确的颜色重建。

  • 通过 GPIO 控制信号启动摄像头。

  • 配置 VDMA 与 DDR 进行高效读写。

完整软件项目已上传至我的 GitHub,可供参考与复用。

#include <stdio.h>
#include "math.h"
#include <ctype.h>
#include <stdlib.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xiicps.h"
#include "i2c/PS_i2c.h"
#include "demosaic/demosaic.h"
#include "cam_config.h"
#include "config.h"
#include "sleep.h"

#include "xil_cache.h"

#include "xgpiops.h"
#include "xscugic.h"
#include "vtc.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"

//#include "ff.h"
/* ------------------------------------------------------------ */
/*				Global Variables								*/
/* ------------------------------------------------------------ */

#define LED_MIO	25
#define CAM1_EMIO	26
#define CAM2_EMIO	27

XAxiVdma vdma;
XAxiVdma_DmaSetup vdmaDMA;
XAxiVdma_Config *vdmaConfig;

XVtc Vtc_inst;

//static int WriteError;

int wr_index=0;
int rd_index=0;


XIicPs ps_i2c0;
XIicPs ps_i2c1;
XGpioPs GPIO_PTR ;


int PsGpioSetup() ;

/*
 * Framebuffers for video data
 */

u8 frameBuf0[1][DEMO_MAX_FRAME] __attribute__ ((aligned(4096)));
u8 *pFrames0; 


void InitVideoFmt(XIicPs *IicInstance,int w, int h)
{

	i2c_reg16_write(IicInstance, 0x36, 0x3808, (w>>8)&0xff);
	i2c_reg16_write(IicInstance, 0x36, 0x3809, (w>>0)&0xff);
	i2c_reg16_write(IicInstance, 0x36, 0x380a, (h>>8)&0xff);
	i2c_reg16_write(IicInstance, 0x36, 0x380b, (h>>0)&0xff);

}

void InitDisplay()
{
    Vtc_init(&Vtc_inst,VMODE_1280x720);
    
}

int main(void)
{

	int i;
    int Status;

	PsGpioSetup() ;

    for (i = 0; i < 1; i++) 
	{
		pFrames0 = frameBuf0[i];
	}
	
	demosaic_init(XPAR_V_DEMOSAIC_0_BASEADDR,VIDEO_COLUMNS,VIDEO_ROWS);

	i2c_init(&ps_i2c0,100000);

    XGpioPs_WritePin(&GPIO_PTR, CAM1_EMIO, 1) ;
	usleep(500000);
	XGpioPs_WritePin(&GPIO_PTR, CAM1_EMIO, 0) ;
	usleep(500000);
	XGpioPs_WritePin(&GPIO_PTR, CAM1_EMIO, 1) ;
	usleep(500000);

	sensor_init(&ps_i2c0);
    InitVideoFmt(&ps_i2c0,VIDEO_COLUMNS,VIDEO_ROWS);



	InitDisplay();

	xil_printf("config done!\r\n");

    vdmaConfig = XAxiVdma_LookupConfig(XPAR_AXI_VDMA_0_BASEADDR);
	XAxiVdma_CfgInitialize(&vdma, vdmaConfig, vdmaConfig->BaseAddress);
	//video = VMODE_1280x720;
	vdmaDMA.FrameDelay = 0;
	vdmaDMA.EnableCircularBuf = 1;
	vdmaDMA.EnableSync = 0;
	vdmaDMA.PointNum = 0;
	vdmaDMA.EnableFrameCounter = 0;

	vdmaDMA.VertSizeInput = 720;
	vdmaDMA.HoriSizeInput = (1280)*3;
	vdmaDMA.FixedFrameStoreAddr = 0;
	vdmaDMA.FrameStoreStartAddr[0] = (u32)  pFrames0[0];
	vdmaDMA.Stride = (1280)*3;

	XAxiVdma_DmaConfig(&vdma, XAXIVDMA_WRITE, &(vdmaDMA));
    XAxiVdma_DmaSetBufferAddr(&vdma, XAXIVDMA_WRITE,vdmaDMA.FrameStoreStartAddr);

	XAxiVdma_DmaConfig(&vdma, XAXIVDMA_READ, &(vdmaDMA));
	XAxiVdma_DmaSetBufferAddr(&vdma, XAXIVDMA_READ,vdmaDMA.FrameStoreStartAddr);


	XAxiVdma_DmaStart(&vdma, XAXIVDMA_WRITE);
	//Status = XAxiVdma_StartParking(&vdma, 0, XAXIVDMA_WRITE);
	XAxiVdma_DmaStart(&vdma, XAXIVDMA_READ);
	//XAxiVdma_StartParking(&vdma, 0, XAXIVDMA_READ);

	while(1){
		XGpioPs_WritePin(&GPIO_PTR, LED_MIO, 0) ;
		usleep(500000);
		XGpioPs_WritePin(&GPIO_PTR, LED_MIO, 1) ;
		usleep(500000);
	}


	return 0;
}


int PsGpioSetup()
{
	XGpioPs_Config *GPIO_CONFIG ;
	int Status ;


	GPIO_CONFIG = XGpioPs_LookupConfig(XPAR_XGPIOPS_0_DEVICE_ID) ;

	Status = XGpioPs_CfgInitialize(&GPIO_PTR, GPIO_CONFIG, GPIO_CONFIG->BaseAddr) ;
	if (Status != XST_SUCCESS)
	{
		return XST_FAILURE ;
	}

	XGpioPs_SetDirectionPin(&GPIO_PTR, LED_MIO, 1) ;
	XGpioPs_SetOutputEnablePin(&GPIO_PTR, LED_MIO, 1) ;

	return XST_SUCCESS ;
}

ILA 验证

当系统软件运行时,我们可以借助 ILA 来验证图像处理流水线是否按预期工作。

这些 ILA 在系统优化与调试过程中也发挥着关键作用。

在 Vivado 硬件管理器中,每个 ILA 会被映射为一个数字编号,映射关系如下:

  • ILA1:Memory ILA

  • ILA2:Output ILA

  • ILA3:LCD LVDS ILA

  • ILA4:Video ILA

验证的第一步是监控 AXI4-Stream to Video Out 模块的状态信号

该 IP 会输出多个指示信号,用于表征 AXI 视频流与视频时序信号是否同步。

如果输入的视频时序存在不匹配或不稳定的情况,该模块将无法锁定,导致视频无法输出。

由于该模块内部包含 FIFO 存储器,我们可以通过 ILA 观察其上溢和下溢状态信号。这些信号对于诊断流水线中的数据不足(data starvation)或背压(backpressure)等性能问题尤为重要,能够指导我们改进存储带宽或缓冲策略。

在 ILA1(即 Output ILA)上观察这些信号,可以看到包含视频数据的 AXI Stream 信号与视频时序控制器生成的时序信号已经保持同步。如果 AXI Stream 信号格式不匹配(例如视频格式不符),AXI4 Stream to Video Out 模块将无法完成同步锁定。

验证过程的下一步是检查 LCD LVDS 输出接口。该阶段的关键状态指示可以确认内部时钟是否锁定,以及接口是否成功启用向显示屏传输数据。监控这些信号,有助于确保序列化视频流被正确生成并传输至 LCD 面板,若出现时钟错误或链路未启用等问题,也能迅速定位。

在验证图像处理通路本身时,首先要检查的是MIPI CSI-2 RX 子系统的视频输出

在此阶段,我们应该观察到每个时钟周期输出 4 像素的 10 bit 原始数据。如果相机配置或 MIPI 接口存在问题,通常会在此处显现为无视频输出或格式异常。验证此输出有助于确认相机初始化是否正确以及 MIPI 链路是否正常建立。

MIPI CSI-2 RX 子系统的输出会送入Demosaic去马赛克模块,它会将 Bayer 格式的 10 位原始像素转换为 30 位 RGB 格式(每个颜色通道 10 位)。由于流水线保持每个时钟处理 4 像素的吞吐量,去马赛克模块输出的 AXI4-Stream 数据总宽度为 120 位(4 像素×30 位),在维持高吞吐量的同时提供完整重构的色彩数据。

LCD 显示屏需要 24 位 RGB 像素(每个颜色通道 8 位)。为满足这一要求,AXI 子集转换器将每像素深度从 30 位压缩至 24 位。系统继续保持每个时钟处理 4 像素的速率,因此转换器输出总线宽度为 96 位(4 像素×24 位),与下游视频输出路径的格式要求完全匹配。

在写入路径上,我们可以观察到 AXI4 总线将处理后的视频帧写入 DDR 存储器的过程。这些传输由 VDMA 发起,它作为 AXI4-Stream 视频流水线与 AXI4 存储器映射接口的桥梁,通过片上网络(NoC)实现帧数据的高效存储。监控这一过程可确保帧缓冲正确写入存储器,供后续读取显示。

读取路径始于 VDMA 通过 NoC 发起 AXI4 读操作,从 DDR 存储器中获取视频帧。这些操作将存储的帧数据重新送回 AXI4-Stream 域,使其能在流水线中继续流向显示端。观察这些 AXI4 读操作可以确认存储器访问功能正常,且帧数据的获取与视频输出时序保持同步。

图像处理流水线的最后环节是 VDMA 输出的 AXI4-Stream 信号,该接口每个时钟周期传输 1 个像素。该数据流输入 AXI4-Stream to Video Out 模块,与时序信号同步后输出至显示端。这一环节标志着系统从基于内存的缓冲机制向实时视频输出的转换,至此,整个图像处理流程闭环完成。

通过观测上述所有 ILA 信号,我们能够深入了解图像处理流水线的内部运行状态,有效排查和定位可能出现的各类问题。

通常这些问题可追溯至软件配置错误或单个 IP 核模块参数设置不当——在早期系统搭建和集成阶段尤为常见。

当然,判断系统是否正常工作的最直观方式仍然是——屏幕上成功显示出图像。但当遇到异常情况时,ILA 提供的深层信号可见性将成为故障诊断的关键工具。

总结
 

在本项目中,我们探讨了如何在 Versal AI Edge 器件上构建基础的图像处理流水线并验证其功能。

无论是图像识别、智能驾驶,还是工业检测,只要有图像数据的地方,就离不开这条看不见的流水线。而我们今天所做的,就是让它“可见”。

通过利用 ChipScope 及 ILA,我们能够观察并验证设计中的关键点,确保每个阶段都按预期运行。这种实时可视化功能使我们能够快速有效地识别在集成或应用阶段系统可能出现的问题及其根本原因,使后续的开发过程变得更加顺畅、可靠。


芯驿电子自 2012 年成立以来,旗下 AUMO 与 ALINX 两大品牌,在智能车载与 FPGA 行业解决方案领域持续深耕。

ALINX 提供完整的用户开发手册和工具链与全备的技术支持,帮助您缩短从原型到量产的周期。欢迎访问 ALINX 官网了解更多详情。

原文:Using ChipScope to Debug AMD Versal Designs - Hackster.io

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-A. PostgreSQL常用函数速查表

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL常用函数速查表:从数据清洗到分析的全场景工具集引言一、字符串处理函数1.1 基础操作函数1.2 模式匹配函数(正则表达式)二、数值计算函数2.1 基础运算函数2.2 统计相关函数三、日期与时间函…

【时空图神经网络 交通】相关模型2:STSGCN | 时空同步图卷积网络 | 空间相关性,时间相关性,空间-时间异质性

注:仅学习使用~ 前情提要: 【时空图神经网络 & 交通】相关模型1:STGCN | 完全卷积结构,高效的图卷积近似,瓶颈策略 | 时间门控卷积层:GLU(Gated Linear Unit),一种特殊的非线性门控单元目录 STSGCN-2020年1.1 背景1.2 模型1.2.1 问题背景:现有模型存在的问题1.2…

docker 学习记录

docker pull nginx docker 将本地nginx快照保存到当前文件夹下 docker save -o nginx.tar nginx:latestdocker 将本地nginx 加载 docker load -i nginx.tar docker运行nginx在80端口 docker run --name dnginx -p 80:80 -d nginxredis启动 docker run --name mr -p 6379:6379 -…

南京邮电大学金工实习答案

一、金工实习的定义 金工实习是机械类专业学生一项重要的实践课程&#xff0c;它绝非仅仅只是理论知识在操作层面的简单验证&#xff0c;而是一个全方位培养学生综合实践能力与职业素养的系统工程。从本质上而言&#xff0c;金工实习是学生走出教室&#xff0c;亲身踏入机械加…

世界模型+大模型+自动驾驶 论文小汇总

最近看了一些论文&#xff0c;懒得一个个写博客了&#xff0c;直接汇总起来 文章目录 大模型VLM-ADVLM-E2EOpenDriveVLAFASIONAD&#xff1a;自适应反馈的类人自动驾驶中快速和慢速思维融合系统快系统慢系统快慢结合 世界模型End-to-End Driving with Online Trajectory Evalu…

C++函数三剑客:缺省参数·函数重载·引用的高效编程指南

前引&#xff1a;在C编程中&#xff0c;缺省参数、函数重载、引用是提升代码简洁性、复用性和效率的三大核心机制。它们既能减少冗杂的代码&#xff0c;又能增强接口设计的灵活性。本文将通过清晰的理论解析与实战案列&#xff0c;带你深入理解这三者的设计思想、使用场景以及闭…

SWUST数据结构下半期实验练习题

1068: 图的按录入顺序深度优先搜索 #include"iostream" using namespace std; #include"cstring" int visited[100]; char s[100]; int a[100][100]; int n; void dfs(int k,int n) {if(visited[k]0){visited[k]1;cout<<s[k];for(int i0;i<n;i){i…

机器学习 Day18 Support Vector Machine ——最优美的机器学习算法

1.问题导入&#xff1a; 2.SVM定义和一些最优化理论 2.1SVM中的定义 2.1.1 定义 SVM 定义&#xff1a;SVM&#xff08;Support Vector Machine&#xff0c;支持向量机&#xff09;核心是寻找超平面将样本分成两类且间隔最大 。它功能多样&#xff0c;可用于线性或非线性分类…

答题pk小程序道具卡的获取与应用

道具卡是答题PK小程序中必不可少的一项增加趣味性的辅助应用&#xff0c;那么道具卡是如何获取与应用的呢&#xff0c;接下来我们来揭晓答案&#xff1a; 一、道具卡的获取&#xff1a; 签到获取&#xff1a;在每日签到中签到不仅可获得当日的签到奖励积分&#xff0c;同时连…

leetcode3265. 统计近似相等数对 I-medium

1 题目&#xff1a;统计近似相等数对 I 官方标定难度&#xff1a;中 给你一个正整数数组 nums 。 如果我们执行以下操作 至多一次 可以让两个整数 x 和 y 相等&#xff0c;那么我们称这个数对是 近似相等 的&#xff1a; 选择 x 或者 y 之一&#xff0c;将这个数字中的两个…

【架构篇】代码组织结构设计

代码组织结构设计&#xff1a;模块化分层与高效协作实践 摘要 本文以Java项目为例&#xff0c;解析后端代码组织的标准化结构&#xff0c;涵盖模块划分原则、依赖管理策略及实际应用场景。通过模块化设计提升代码可维护性、团队协作效率及系统扩展能力。 一、模块化设计的核心…

日期数据渲染转换问题

今天在学习Springboot框架时&#xff0c;想做一个非常简单的增删改查巩固一下&#xff0c;结果在数据渲染上出现了一个小问题&#xff0c;如图数据库中的数据一切正常 但是在前端渲染时&#xff0c;是下面这个效果 这是因为数据库存储的日期类型数据在前端渲染时&#xff0c;没…

ubuntu18.04编译qt5.14.2源码

ubuntu18.04编译qt5.14.2源码 文章目录 ubuntu18.04编译qt5.14.2源码[toc]1 前言2 参考文档3 下载源码3.1 方法13.2 方法23.3 方法3 4 ubuntu编译qt源码4.1 环境准备4.2 设置交换分区大小4.3 编译源码4.4 添加环境变量4.5 验证编译结果4.6 编译帮助文档&#xff08;qch&#xf…

创建指定版本的vite项目

1、获取vite的版本号 npm view create-vite versions 注:4.4.1版本即对应着node16版本的项目 2、创建制定版本的vite项目 npm init vite<version>

iOS 初识RunLoop

iOS 初识RunLoop 文章目录 iOS 初识RunLoopRunLoop的概念RunLoop的功能RunLoop和线程的关系RunLoop的结构ModeObserverTimer 和 source小结 RunLoop的核心RunLoop的流程RunLoop的应用AutoreleasePool响应触控事件刷新界面常驻线程网络请求NSTimer 和 CADisplayLinkNSTimerGCDTi…

电子电路仿真实验教学平台重磅上线!——深圳航天科技创新研究院倾力打造,助力高校教学数字化转型

在传统电子电路课堂中&#xff0c;实验室的灯光总与高昂的成本、拥挤的设备、反复的耗材损耗相伴&#xff0c;而教师不得不面对这样的现实&#xff1a;有限的硬件资源束缚着教学深度&#xff0c;不可逆的实验风险制约着创新探索&#xff0c;固化的时空场景阻碍着个性化学习。当…

搭建一个WordPress网站需要多少成本

WordPress 最初可能只是一个简单的博客平台。但近年来&#xff0c;它不仅成为了最好的博客平台&#xff0c;还成为了一个全面的内容管理系统。白宫、jQuery、NGINX、《纽约时报》等企业都把 WordPress 作为自己的网上家园。 不过&#xff0c;它们只是其中的佼佼者。根据 Built…

Python数据可视化 - Pyecharts绘图示例

文章目录 一、Pyecharts简介及安装1. Pyecharts简介2. 安装Pyecharts 二、准备数据三、饼图示例1. 初始化选项配置2. 饼图相关设置3. 全局配置项3.1 标题配置项3.2 图例配置项3.3 提示框配置项3.4 工具箱配置项3.5 视觉映射配置项 4. 系列配置项4.1 标签选项配置4.2 图元样式配…

NC016NC017美光固态芯片NC101NC102

NC016NC017美光固态芯片NC101NC102 在存储技术的演进历程中&#xff0c;美光科技的NC016、NC017、NC101与NC102系列固态芯片&#xff0c;凭借其技术创新与市场适应性&#xff0c;成为行业关注的焦点。本文将从技术内核、产品性能、行业动向、应用场景及市场价值五个维度&#…

[Android] 青木扫描全能文档3.0,支持自动扫描功能

声明&#xff1a;根据许多帖友的反馈&#xff0c;我也根据重新实测得出结论&#xff1a;该app是提供一天的体验时间&#xff0c;后续还是采取收费才能使用功能的措施。因为现在市面上免费使用的扫描工具很少了&#xff0c;所以当初我初步测试感觉软件不错就发布了出来&#xff…