16.2 VDMA视频转发实验之模拟源

文章目录

  • 1 实验任务
  • 2 系统框图
  • 3 硬件设计
    • 3.1 IP核配置
    • 3.2 注意事项
    • 3.3 自定义IP核源码
  • 4 软件设计
    • 4.1 注意事项
    • 4.2 工程源码
      • 4.2.1 main.c文件

1 实验任务

基于14.1,相较于16.1,使用自定义IP核vid_gen_motion替换Xilinx TPG IP核。

2 系统框图

基于14.1,添加自定义IP核vid_gen_motion作为视频源,通过Video In to AXI4-Stream IP核转换后,连接到VDMA的写通道,如下图所示:
在这里插入图片描述

3 硬件设计

3.1 IP核配置

  1. 配置VDMA IP核
    • (1)Basic页面
      • 1)Frame Buffers:选择默认值3,即缓存3帧图像数据
      • 2)Enable Write Channel:勾选,使能写通道
      • 3)Write Burst Size:选择256,最大化传输效率
      • 4)Line Buffer Depth:选择2048,图像分辨率为1920x1080,能够缓存一行像素数据
        在这里插入图片描述
    • (2)Advanced页面
      • 1)保持默认值,采用动态同步锁相模式,写通道为主,读通道为从
        在这里插入图片描述
  2. 配置Video In to AXI4-Stream IP核
    • (1)Clock Mode:点选Independent
    • (2)其他保持默认
      在这里插入图片描述
  3. 配置VTC IP核
    • (1)Include AXI4-Lite Interface:不勾选
    • (2)Enable Generation:不勾选
    • (3)Detection Options:保持默认
      在这里插入图片描述
  4. 封装自定义IP核vid_gen_motion并添加,无需配置,默认输出1080p视频。

3.2 注意事项

  1. VTC IP核的Detection Options选择,官方文档pg016中有明确说明,如下图所示:
    在这里插入图片描述
    • (1)上图仅给出hsync和hblank信号的说明,vsync、vblank和data_valid信号亦如此
  2. 为各个接口自动连线:必须手动指定主从接口和互联模块的时钟
    • (1)为VDMA的M_AXI_S2MM接口连线:从接口是PS的S_AXI_HP0接口
      在这里插入图片描述
    • (2)将Video In to AXI4-Stream和VDMA连接起来,为s_axis_s2mm_aclk和aclk时钟连线(选择PS输出的FCLK_CLK1时钟)
      在这里插入图片描述
    • (3)将Video In to AXI4-Stream和VTC连接起来,为VTC的clk时钟连线(选择Clocking Wizard输出的clk_out1时钟,即视频时钟)
      在这里插入图片描述
    • (4)将vid_gen_motion和Video In to AXI4-Stream连接起来,为clk和vid_io_in_clk时钟连线(选择Clocking Wizard输出的clk_out1时钟,即视频时钟)
      在这里插入图片描述

3.3 自定义IP核源码

`timescale 1ns / 1psmodule vid_gen_motion (input     wire         clk,input     wire         clken,input     wire         rstn,output    wire         o_vid_vsync,output    wire         o_vid_vblank,output    wire         o_vid_hsync,output    wire         o_vid_hblank,output    wire         o_vid_active,output    wire [23:0] o_vid_data
);
//***********************************************************************************************
// Constant Functions
//***********************************************************************************************//***********************************************************************************************
// Parameter Definitions
//***********************************************************************************************
// 1080p详细时序参数 (按照SMPTE 274M标准)
// 水平时序
parameter H_ACTIVE  = 1920;  // 有效视频像素数
parameter H_LEFT    = 0;     // 左侧黑边
parameter H_RIGHT   = 0;     // 右侧黑边
parameter H_FP      = 88;    // 行前沿(Front Porch)
parameter H_SYNC    = 44;    // 行同步脉冲
parameter H_BP      = 148;   // 行后沿(Back Porch)
parameter H_TOTAL   = H_LEFT + H_ACTIVE + H_RIGHT + H_FP + H_SYNC + H_BP; // 2200// 垂直时序
parameter V_ACTIVE  = 1080;  // 有效视频行数
parameter V_TOP     = 0;     // 顶部黑边
parameter V_BOTTOM  = 0;     // 底部黑边
parameter V_FP      = 4;     // 场前沿(Front Porch)
parameter V_SYNC    = 5;     // 场同步脉冲
parameter V_BP      = 36;    // 场后沿(Back Porch)
parameter V_TOTAL   = V_TOP + V_ACTIVE + V_BOTTOM + V_FP + V_SYNC + V_BP; // 1125// 方块参数
parameter SQUARE_SIZE = 20;
parameter SQUARE_SPEED = 1;// 关键边界定义 (保留完整边框参数)
// 水平方向 (严格按您要求的顺序: LEFT -> ACTIVE -> RIGHT -> FP -> SYNC -> BP)
localparam H_SYNC_START   = H_LEFT + H_ACTIVE + H_RIGHT + H_FP;
localparam H_SYNC_END     = H_SYNC_START + H_SYNC;
localparam H_ACTIVE_START = H_LEFT;
localparam H_ACTIVE_END   = H_ACTIVE_START + H_ACTIVE;
localparam H_BLANK_START  = H_LEFT + H_ACTIVE + H_RIGHT;
localparam H_BLANK_END    = H_TOTAL;// 垂直方向 (严格按您要求的顺序: TOP -> ACTIVE -> BOTTOM -> FP -> SYNC -> BP)
localparam V_SYNC_START   = V_TOP + V_ACTIVE + V_BOTTOM + V_FP;
localparam V_SYNC_END     = V_SYNC_START + V_SYNC;
localparam V_ACTIVE_START = V_TOP;
localparam V_ACTIVE_END   = V_ACTIVE_START + V_ACTIVE;
localparam V_BLANK_START  = V_TOP + V_ACTIVE + V_BOTTOM;
localparam V_BLANK_END    = V_TOTAL;
//***********************************************************************************************
// Signal Declarations
//***********************************************************************************************
reg   [15:0]   h_cnt;
reg   [15:0]   v_cnt;reg   [15:0]   square_x;
reg   [15:0]   square_y;reg            x_dir; // 0=右移, 1=左移
reg            y_dir; // 0=下移, 1=上移reg            vid_vsync;
reg            vid_vblank;
reg            vid_hsync;
reg            vid_hblank;
reg            vid_active;
reg   [23:0]   vid_data;
//***********************************************************************************************
// Pipeline Inputs
//***********************************************************************************************//***********************************************************************************************
// Code
//***********************************************************************************************
// 水平计数器
always @(posedge clk or negedge rstn) beginif (!rstn) h_cnt <= 16'd0;else if (clken) begin if (h_cnt < H_TOTAL-1) h_cnt <= h_cnt + 1;else h_cnt <= 16'd0;end      
end// 垂直计数器
always @(posedge clk or negedge rstn) beginif (!rstn) v_cnt <= 16'd0;else if (clken) begin  if (h_cnt == H_TOTAL-1)if (v_cnt < V_TOTAL-1) v_cnt <= v_cnt + 1;else v_cnt <= 16'd0;elsev_cnt <= v_cnt;   end   
end// 方块移动逻辑(反弹模式)
always @(posedge clk or negedge rstn) beginif (!rstn) beginsquare_x <= 16'd0;square_y <= 16'd0;x_dir <= 0;y_dir <= 0;endelse if (clken) beginif (v_cnt == V_TOTAL-1 && h_cnt == H_TOTAL-1) begin// 水平移动if (x_dir == 0) begin // 向右移动if (square_x + SQUARE_SIZE + SQUARE_SPEED <= H_ACTIVE)square_x <= square_x + SQUARE_SPEED;else beginsquare_x <= H_ACTIVE - SQUARE_SIZE; // 贴住右边界x_dir <= 1; // 改为左移endendelse begin // 向左移动if (square_x >= SQUARE_SPEED)square_x <= square_x - SQUARE_SPEED;else beginsquare_x <= 0; // 贴住左边界x_dir <= 0; // 改为右移endend// 垂直移动if (y_dir == 0) begin // 向下移动if (square_y + SQUARE_SIZE + SQUARE_SPEED <= V_ACTIVE)square_y <= square_y + SQUARE_SPEED;else beginsquare_y <= V_ACTIVE - SQUARE_SIZE; // 贴住下边界y_dir <= 1; // 改为上移endendelse begin // 向上移动if (square_y >= SQUARE_SPEED)square_y <= square_y - SQUARE_SPEED;else beginsquare_y <= 0; // 贴住上边界y_dir <= 0; // 改为下移endendendend   
end// 行同步信号生成
always @(posedge clk or negedge rstn) beginif (!rstn) vid_hsync <= 1'b0;else if (clken) begin if (h_cnt >= H_SYNC_START && h_cnt < H_SYNC_END)vid_hsync <= 1'b1;elsevid_hsync <= 1'b0;end      
end// 行消隐信号生成
always @(posedge clk or negedge rstn) beginif (!rstn) vid_hblank <= 1'b0;else if (clken) begin if (h_cnt >= H_BLANK_START && h_cnt < H_BLANK_END)vid_hblank <= 1'b1;elsevid_hblank <= 1'b0;end         
end// 场同步信号生成
always @(posedge clk or negedge rstn) beginif (!rstn) vid_vsync <= 1'b0;else if (clken) begin if (v_cnt >= V_SYNC_START && v_cnt < V_SYNC_END)vid_vsync <= 1'b1;elsevid_vsync <= 1'b0;end
end// 场消隐信号生成
always @(posedge clk or negedge rstn) beginif (!rstn) vid_vblank <= 1'b0;else if (clken) begin if (v_cnt >= V_BLANK_START && v_cnt < V_BLANK_END)vid_vblank <= 1'b1;elsevid_vblank <= 1'b0;end      
end// 数据有效信号生成
always @(posedge clk or negedge rstn) beginif (!rstn) vid_active <= 1'b0;else if (clken) begin if (h_cnt >= H_ACTIVE_START && h_cnt < H_ACTIVE_END &&v_cnt >= V_ACTIVE_START && v_cnt < V_ACTIVE_END)vid_active <= 1'b1;elsevid_active <= 1'b0;end         
end// 视频数据生成
always @(posedge clk or negedge rstn) beginif (!rstn) beginvid_data <= 24'hFFFFFF; // 默认白色背景endelse if (clken) begin if (h_cnt >= H_ACTIVE_START && h_cnt < H_ACTIVE_END &&v_cnt >= V_ACTIVE_START && v_cnt < V_ACTIVE_END)// 检查当前像素是否在方块区域内if (h_cnt >= square_x && h_cnt < square_x + SQUARE_SIZE &&v_cnt >= square_y && v_cnt < square_y + SQUARE_SIZE)vid_data <= 24'h000000; // 黑色方块elsevid_data <= 24'hFFFFFF; // 白色背景else beginvid_data <= 24'd0; // 消隐区输出0end   end
end
//***********************************************************************************************
// Outputs
//***********************************************************************************************
assign o_vid_vsync  = vid_vsync;
assign o_vid_vblank = vid_vblank;
assign o_vid_hsync  = vid_hsync;
assign o_vid_hblank = vid_hblank;
assign o_vid_active = vid_active;
assign o_vid_data   = vid_data;endmodule

4 软件设计

4.1 注意事项

  1. 自定义IP核vid_gen_motion生成一个背景为纯白,叠加一个黑色移动小方块的视频
  2. 通过VIO控制vid_gen_motion的clken信号
    • (1)当clken拉低时
      • 1)vid_gen_motion IP核暂停产生视频数据
      • 2)显示器上小方块停止移动
    • (2)当clken拉高时
      • (1)vid_gen_motion IP核恢复产生视频数据
      • (2)显示器上小方块继续从停止的位置开始移动
    • (3)关于VTC输出的locked信号
      • 1)控制Video In to AXI4-Stream的axis_stream信号,该信号"enable/disable writes into FIFO"
      • 2)在clken信号先拉底后拉高的过程中会有一个失锁(locked=0)和重新锁定(locked=1)的过程
      • 3)测试发现:在clken拉低后
        • locked信号并未拉低(下图中axis_stream信号依然为高)
        • Video In to AXI4-Stream的Video In接口,同步和消隐信号保持为低,active_video保持为高,该现象和clken停止的时机有关
          在这里插入图片描述
        • Video In to AXI4-Stream的AXI4-Stream接口,TREADY和TVALID信号一直为高,说明Video In to AXI4-Stream一直向VDMA写通道提供数据;但是,因为TUSER和TLAST信号的缺失(一直保持为低),VDMA写通道未将Video In to AXI4-Stream提供的数据写入PS侧DDR中(因为显示器上小方块停止移动)
          在这里插入图片描述
      • 4)测试发现:在clken拉高后
        • locked信号会先拉低后拉高,表示VTC经过一个失锁然后再次锁定的过程,如下图所示
          在这里插入图片描述
      • 5)测试发现:locked信号有时也会在clken拉低后立即拉低,应该与clken拉低的时机和VTC的检测机制有关系
      • 6)测试证明:VTC和VDMA的视频帧隔离和处理功能很强大
  3. 通过PS控制VDMA写通道启停
    • (1)当VDMA写通道停止时
      • 1)VDMA写通道暂停接收视频数据
        • Video In to AXI4-Stream的AXI4-Stream接口的TREADY信号拉低,如下图所示
          在这里插入图片描述
        • Video In to AXI4-Stream的FIFO仍在接收vid_gen_motion提供的视频数据,导致FIFO溢出,overflow信号不停拉高(通过观察应该是在每一行开始后不久拉高一个时钟周期),如下图所示
          在这里插入图片描述
      • 2)VDMA读通道依然在发送数据
        • 显示器上小方块停止移动
        • 说明VDMA读通道在重复发送同一帧视频数据,该帧视频数据是VDMA写通道在停止前写入的最后一帧
        • 符合动态同步锁相模式的工作机制,即读通道(Dynamic Genlock Slave)会操作写通道(Dynamic Genlock Master)上一个周期操作的帧
    • (2)当VDMA写通道重启据时
      • 1)Video In to AXI4-Stream的FIFO不再溢出
      • 2)显示器上小方块继续开始移动,但起始位置已不再是之前停止的位置,而是vid_gen_motion产生的视频数据中小方块的当前位置
    • (3)再次证明:VTC和VDMA的视频帧隔离和处理功能的强大

4.2 工程源码

4.2.1 main.c文件

/********************************************************************/#include "vdma/vdma_api.h"#include "xparameters.h"
#include "stdio.h"
#include "sleep.h"/********************************************************************/#define VDMA_DEVICE_ID		XPAR_AXIVDMA_0_DEVICE_ID
#define MEMORY_BASEADDR		XPAR_PS7_DDR_0_S_AXI_BASEADDR#define IMAGE_WIDTH			1920
#define IMAGE_HEIGHT		1080/********************************************************************//********************************************************************/XAxiVdma VdmaInst;int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);/********************************************************************/int main()
{//int Status;//printf("Vdma Video Forward Test.\n");// 启动VDMA读写操作Status = run_vdma_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0, BOTH);if (Status == XST_FAILURE) {printf("Error : run vdma frame buffer failed.\n");return XST_FAILURE;}//while (1) {//sleep(10);printf("Stop vdma channel.\n");
//    	XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_WRITE);//sleep(15);printf("Start vdma channel.\n");
//		XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_WRITE);}//return XST_SUCCESS;
}/*****************************************************************************//*****************************************************************************/

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

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

相关文章

深度学习之用CelebA_Spoof数据集搭建一个活体检测-训练好的模型用MNN来推理

一、模型转换准备 首先确保已完成PyTorch到ONNX的转换&#xff1a;深度学习之用CelebA_Spoof数据集搭建活体检测系统&#xff1a;模型验证与测试。这里有将PyTorch到ONNX格式的模型转换。 二、ONNX转MNN 使用MNN转换工具进行格式转换&#xff1a;具体的编译过程可以参考MNN的…

JVM学习专题(一)类加载器与双亲委派

目录 1、JVM加载运行全过程梳理 2、JVM Hotspot底层 3、war包、jar包如何加载 4、类加载器 我们来查看一下getLauncher&#xff1a; 1.我们先查看getExtClassLoader() 2、再来看看getAppClassLoader(extcl) 5、双亲委派机制 1.职责明确&#xff0c;路径隔离​&#xff…

部署安装gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm

目录 ​编辑 实验环境 所需软件 实验开始 安装部署gitlab171.配置清华源仓库&#xff08;版本高的系统无需做&#xff09;vim /etc/yum.repos.d/gitlab-ce.repo 2.提前下载包dnf localinstall gitlab-ce-17.9.7-ce.0.el8.x86_64.rpm --rocklinux 3.修改配…

使用LoRA微调Qwen2.5-VL-7B-Instruct完成电气主接线图识别

使用LoRA微调Qwen2.5-VL-7B-Instruct完成电气主接线图识别 动机 任务适配需求 Qwen2.5-VL在视觉理解方面表现优异&#xff0c;但电气主接线图识别需要特定领域的结构化输出能力&#xff08;如设备参数提取、拓扑关系解析&#xff09;。微调可增强模型对专业符号&#xff08;如…

系统集成项目管理工程师学习笔记

第九章 项目管理概论 1、项目基本要素 项目基础 项目是为创造独特的产品、服务或成果而进行的临时性工作。 项目具有临时性、独特性、渐进明细的特点。项目的“临时性”是指项目只有明确的起点和终点。“临时性”并一定意味着项目的持续时间短。 项目可宣告结束的情况&…

Secs/Gem第七讲(基于secs4net项目的ChatGpt介绍)

好的&#xff0c;那我们现在进入&#xff1a; 第七讲&#xff1a;掉电重连后&#xff0c;为什么设备不再上报事件&#xff1f;——持久化与自动恢复的系统设计 关键词&#xff1a;掉电恢复、状态重建、初始化流程、SecsMessage 缓存机制、自动重连、事件再注册 本讲目标 你将理…

室内定位:热门研究方向与未解难题深度解析

I. 引言:对普适性室内定位的持续探索 A. 室内定位在现代应用中的重要性 室内定位系统(IPS)正迅速成为众多应用领域的基石技术,其重要性源于现代社会人们约70%至90%的时间在室内度过的事实 1。这些应用横跨多个行业,包括应急响应 1、智能建筑与智慧城市 6、医疗健康(如病…

Android学习总结之Glide自定义三级缓存(实战篇)

一、为什么需要三级缓存 内存缓存&#xff08;Memory Cache&#xff09; 内存缓存旨在快速显示刚浏览过的图片&#xff0c;例如在滑动列表时来回切换的图片。在 Glide 中&#xff0c;内存缓存使用 LruCache 算法&#xff08;最近最少使用&#xff09;&#xff0c;能自动清理长…

Linux的文件查找与压缩

查找文件 find命令 # 命令&#xff1a;find 路径范围 选项1 选项1的值 \[选项2 选项2 的值…]# 作用&#xff1a;用于查找文档&#xff08;其选项有55 个之多&#xff09;# 选项&#xff1a;# -name&#xff1a;按照文档名称进行搜索&#xff08;支持模糊搜索&#xff0c;\* &…

python处理异常,JSON

异常处理 #异常处理 # 在连接MySQL数据库的过程中&#xff0c;如果不能有效地处理异常&#xff0c;则异常信息过于复杂&#xff0c;对用户不友好&#xff0c;暴露过多的敏感信息 # 所以&#xff0c;在真实的生产环境中&#xff0c; 程序必须有效地处理和控制异常&#xff0c;按…

线程的两种实现方式

线程的两种实现方式——内核支持线程&#xff08;kernal Supported Thread, KST&#xff09;&#xff0c; 用户级线程&#xff08;User Level Thread, ULT&#xff09; 1. 内核支持线程 顾名思义&#xff0c;内核支持线程即为在内核支持下的那些线程&#xff0c;它们的创建&am…

vue3基础学习(上) [简单标签] (vscode)

目录 1. Vue简介 2. 创建Vue应用 2.1 下载JS文件 2.2 引用JS文件 2.3 调用Vue方法​编辑 2.4 运行一下试试: 2.5 代码如下 3.模块化开发模式 3.1 Live Server插件 3.2 运行 4. 常用的标签 4.1 reactive 4.1.1 运行结果 4.1.2 代码: 4.2 ref 4.2.1 运行结果 4.2.2…

自定义分区器-基础

什么是分区 在 Spark 里&#xff0c;弹性分布式数据集&#xff08;RDD&#xff09;是核心的数据抽象&#xff0c;它是不可变的、可分区的、里面的元素并行计算的集合。 在 Spark 中&#xff0c;分区是指将数据集按照一定的规则划分成多个较小的子集&#xff0c;每个子集可以独立…

深入解析HTTP协议演进:从1.0到3.0的全面对比

HTTP协议作为互联网的基础协议&#xff0c;经历了多个版本的迭代演进。本文将详细解析HTTP 1.0、HTTP 1.1、HTTP/2和HTTP/3的核心特性与区别&#xff0c;帮助开发者深入理解网络协议的发展脉络。 一、HTTP 1.0&#xff1a;互联网的奠基者 核心特点&#xff1a; 短连接模式&am…

基于windows环境Oracle主备切换之后OGG同步进程恢复

基于windows环境Oracle主备切换之后OGG同步进程恢复 场景&#xff1a;db1是主库&#xff0c;db2是备库&#xff0c;ogg从db2备库抽取数据同步到目标数据库 db1 - db2(ADG) – ogg – targetdb 场景&#xff1a;db2是主库&#xff0c;db1是备库&#xff0c;ogg从db1备库抽取数…

微服务,服务粒度多少合适

项目服务化好处 复用性&#xff0c;消除代码拷贝专注性&#xff0c;防止复杂性扩散解耦合&#xff0c;消除公共库耦合高质量&#xff0c;SQL稳定性有保障易扩展&#xff0c;消除数据库解耦合高效率&#xff0c;调用方研发效率提升 微服务拆分实现策略 统一服务层一个子业务一…

【工奥阀门科技有限公司】签约智橙PLM

近日&#xff0c;工奥阀门科技有限公司正式签约了智橙泵阀行业版PLM。 忠于质量&#xff0c;臻于服务&#xff0c;精于研发 工奥阀门科技有限公司&#xff08;以下简称工奥阀门&#xff09;坐落于浙江永嘉&#xff0c;是一家集设计、开发、生产、销售、安装、服务为一体的阀门…

2025-5-15Vue3快速上手

1、setup和选项式API之间的关系 (1)vue2中的data,methods可以与vue3的setup共存 &#xff08;2&#xff09;vue2中的data可以用this读取setup中的数据&#xff0c;但是反过来不行&#xff0c;因为setup中的this是undefined &#xff08;3&#xff09;不建议vue2和vue3的语法混用…

基于智能推荐的就业平台的设计与实现(招聘系统)(SpringBoot Thymeleaf)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

什么是路由器环回接口?

路由器环回接口&#xff08;LoopbackInterface&#xff09;是网络设备中的一种逻辑虚拟接口&#xff0c;不依赖物理硬件&#xff0c;但在网络配置和管理中具有重要作用。以下是其核心要点&#xff1a; 一、基本特性 1.虚拟性与稳定性 环回接口是纯软件实现的逻辑接口&#x…