FPGA纯verilog解码SDI视频 纯逻辑资源实现 提供2套工程源码和技术支持

news2024/11/25 6:49:12

目录

  • 1、前言
  • 2、硬件电路解析
    • SDI摄像头
    • Gv8601a单端转差
    • GTX解串
    • SDI解码
    • VGA时序恢复
    • YUV转RGB
    • 图像输出
    • FDMA图像缓存
    • HDMI输出
  • 3、工程1详解:无缓存输出
  • 4、工程2详解:缓存3帧输出
  • 5、上板调试验证并演示
  • 6、福利:工程代码的获取

1、前言

FPGA实现SDI视频编解码目前有两种方案:
一是使用专用编解码芯片,比如典型的接收器GS2971,发送器GS2972,优点是简单,比如GS2971直接将SDI解码为并行的YCRCB,缺点是成本较高,可以百度一下GS2971的价格;
另一种方案是使用FPGA实现编解码,利用FPGA的GTP/GTX资源实现解串,优点是合理利用了FPGA资源,GTP/GTX资源不用白不用,缺点是操作难度大一些,对FPGA水平要求较高。
本文详细描述了FPGA纯verilog解码SDI视频的实现设计方案,工程代码编译通过后上板调试验证,文章末尾有演示视频,可直接项目移植,适用于在校学生做毕业设计、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
本设计提供两套vivado工程;
一是SDI 1080P@30Hz帧视频输入解码后,无缓存直接HDMI 1080P@30Hz帧输出;
二是SDI 1080P@30Hz帧视频输入解码后,缓存3帧后HDMI 1080P@60Hz帧输出;
关于SDI的理论知识部分,可自行搜索一下,很多大佬讲得很详细,也可以参考我之前写的文章:点击查看:SDI解码详解

2、硬件电路解析

硬件电路连接如下:
在这里插入图片描述

SDI摄像头

我用到的SDI摄像头输出视频分辨率1080P@30Hz;根据不同相机有所区别;

Gv8601a单端转差

Gv8601a起到均衡 EQ 功能,这里选用Gv8601a是因为抄袭了Xilinx官方的板子,当然也可以用其他型号器件。

GTX解串

GTX负责解串,将原始SDI视频解为20位的并行数据,我的板子是K7,所以用GTX,如果是A7的板子则用GTP,这里使用GTX并没有调用IP,而是直接调用GTXE2_CHANNEL和GTXE2_COMMON源语,这一点可谓将Xilinx的GTX资源用到了极致水平,值得好好品读,其实调用IP无非也就是把调用源语变得界面化而已,直接调用源语或许理解更为深刻,这一点,在市面上的所谓FPGA教程里都学不到。

SDI解码

调用SMPTE-SDI IP核实现,GTX只是将高速串行数据解为了并行,但并没有解析SDI协议,SMPTE-SDI IP核则完成了SDI协议的解码,去掉了SDI协议中的数据包信息和控制信息,解析出有效的视频数据,详细的SMPTE-SDI IP核接口定义请参考官方的使用手册;

VGA时序恢复

此模块的作用就是解码恢复出hs、vs以及de信号,即恢复正常的VGA视频时序;
要恢复正常的VGA视频时序,首先得看懂下面这张图:
在这里插入图片描述
根据这张表即可恢复出图像时序,具体看代码,这里一两句话实在讲不清楚,如果要完全讲明白,写5本书都搓搓有余;

YUV转RGB

这里就简单了,YUV4:4:4转RGB8:8:8,几条公式和几行代码的事儿,属于低端操作;
至此,SDI解码过程就完成了,接下来就是图像输出过程;

图像输出

图像输出有两种通路
一种是无缓存直接输出,这种方式的优点是没有延迟,适用于做图传的项目,缺点是不能对图像进行其他处理了;
另一种是缓存输出,这种方式的优点是可以平衡和同步后端的接收,比如后端接收不过来时就可以缓存几帧再输出;另外,如果还需要对图像进行其他处理时也需要缓存,适用于做图像处理的项目,缺点是输出有延迟,根据设置可以延迟多帧,本设计是延迟3帧;
既然需求是多样的,所以我们直接做两个工程。

FDMA图像缓存

我常用的FDMA数据缓存架构,详情请参考我之前的文章:点击查看:FDMA图像缓存

HDMI输出

纯verilog代码实现HDMI发送,输出时序1920x1080P,输出帧率由输入HDMI时钟决定;
HDMI输出顶层接口如下:

module helai_hdmi_out(
	input         clk_hdmi     ,
	input         clk_hdmix5   ,
	input         reset_n      ,
	input         i_vga_hs     ,
	input         i_vga_vs     ,
	input         i_vga_de     ,	
    input  [23:0] i_vga_rgb    ,   
    output        o_hdmi_clk_p ,
    output        o_hdmi_clk_n ,
    output [2: 0] o_hdmi_data_p,
	output [2: 0] o_hdmi_data_n            
);

3、工程1详解:无缓存输出

开发板:Xilinx Kintex7开发板;
开发环境:Vivado2019.1;
输入:SDI摄像头,分辨率1080p@30帧;
输出:HDMI,分辨率1080p@30帧;
工程代码架构如下:
在这里插入图片描述
顶层源码如下:

module helai_sdi_decode_2023(
    input        I_SDI_2_N           ,
    input        I_SDI_2_P           ,		
    input        SDI_GTX_CLK_148_5_N ,	// MGT REFCLKs 148.5 MHz clock
    input        SDI_GTX_CLK_148_5_P ,    
    input        SDI_GTX_CLK_148_35_P,	// MGT REFCLKs 148.35 MHz clock
    input        SDI_GTX_CLK_148_35_N,
    output       HDMI_CLK_P          ,
    output       HDMI_CLK_N          ,
    output [2:0] HDMI_DATA_P         ,
    output [2:0] HDMI_DATA_N                    	
    );

wire        o_vout_clk      ;          
wire        o_vout_hs       ;          
wire        o_vout_vs       ;          
wire        o_vout_de       ;          
wire [23:0] o_vout_rgb      ;          
 
wire        clk_hdmi  ;
wire        clk_hdmix5;
wire        hdmi_rstn ;

helai_sdi_driver u_helai_sdi_driver(
    .I_SDI_2_N           (I_SDI_2_N           ),
    .I_SDI_2_P           (I_SDI_2_P           ),	
    .O_SDI_2_N           (),
    .O_SDI_2_P           (),	
    .SDI_GTX_CLK_148_5_N (SDI_GTX_CLK_148_5_N ),    // MGT REFCLKs 148.5 MHz clock
    .SDI_GTX_CLK_148_5_P (SDI_GTX_CLK_148_5_P ),    
    .SDI_GTX_CLK_148_35_P(SDI_GTX_CLK_148_35_P),   // MGT REFCLKs 148.35 MHz clock
    .SDI_GTX_CLK_148_35_N(SDI_GTX_CLK_148_35_N),
	.o_vout_clk          (o_vout_clk          ),
	.o_vout_hs           (o_vout_hs           ),
	.o_vout_vs           (o_vout_vs           ),
	.o_vout_de           (o_vout_de           ),
    .o_vout_rgb          (o_vout_rgb          )	
);

clk_wiz_1 clk_hdmi (
    .clk_hdmi(clk_hdmi),     // output clk_hdmi
    .clk_hdmi_clkx5(clk_hdmix5),     // output clk_hdmi_clkx5
    .locked(hdmi_rstn),       // output locked
    .clk_in1(o_vout_clk)	// input clk_in1
);      

helai_hdmi_out(
	.clk_hdmi     (clk_hdmi   ),
	.clk_hdmix5   (clk_hdmix5 ),
	.reset_n      (hdmi_rstn  ),
	.i_vga_hs     (o_vout_hs  ),
	.i_vga_vs     (o_vout_vs  ),
	.i_vga_de     (o_vout_de  ),	
    .i_vga_rgb    (o_vout_rgb ),   
    .o_hdmi_clk_p (HDMI_CLK_P ),
    .o_hdmi_clk_n (HDMI_CLK_N ),
    .o_hdmi_data_p(HDMI_DATA_P),
	.o_hdmi_data_n(HDMI_DATA_N)            
);
endmodule

资源消耗和功耗预估如下:
在这里插入图片描述

4、工程2详解:缓存3帧输出

开发板:Xilinx Kintex7开发板;
开发环境:Vivado2019.1;
输入:SDI摄像头,分辨率1080p@30帧;
输出:HDMI,分辨率1080p@60帧;
工程BD如下:
在这里插入图片描述
工程代码架构如下:
在这里插入图片描述
在这里插入图片描述
顶层源码如下:

module helai_sdi_decode_2023(
	input        clk_27m             ,
    input        I_SDI_2_N           ,
    input        I_SDI_2_P           ,		
    input        SDI_GTX_CLK_148_5_N ,	// MGT REFCLKs 148.5 MHz clock
    input        SDI_GTX_CLK_148_5_P ,    
    input        SDI_GTX_CLK_148_35_P,	// MGT REFCLKs 148.35 MHz clock
    input        SDI_GTX_CLK_148_35_N,
    input        i_uart_rx           , 	
	output       o_uart_tx           , 	
// DDR3	
	output [12:0]DDR3_0_addr         ,
	output [2:0] DDR3_0_ba           ,
	output       DDR3_0_cas_n        ,
	output [0:0] DDR3_0_ck_n         ,
	output [0:0] DDR3_0_ck_p         ,
	output [0:0] DDR3_0_cke          ,
	output [3:0] DDR3_0_dm           ,
	inout [31:0] DDR3_0_dq           ,
	inout [3:0]  DDR3_0_dqs_n        ,
	inout [3:0]  DDR3_0_dqs_p        ,
	output [0:0] DDR3_0_odt          ,
	output       DDR3_0_ras_n        ,
	output       DDR3_0_reset_n      ,
	output       DDR3_0_we_n         ,
	output       ddr3_ok             ,
// HDMI_OUT                          
    output       HDMI_CLK_P          ,
    output       HDMI_CLK_N          ,
    output [2:0] HDMI_DATA_P         ,
    output [2:0] HDMI_DATA_N                    	
    );

wire ui_clk_200m;
wire rst_n      ;

wire        ud_r_0_ud_rclk  ;
wire [31:0] ud_r_0_ud_rdata ;
wire 	    ud_r_0_ud_rde   ;
wire        ud_r_0_ud_rvs   ;
wire        ud_w_0_ud_wclk  ;
wire [31:0] ud_w_0_ud_wdata ;
wire        ud_w_0_ud_wde   ;
wire        ud_w_0_ud_wvs   ;

wire        o_vout_clk      ;          
wire        o_vout_hs       ;          
wire        o_vout_vs       ;          
wire        o_vout_de       ;          
wire [23:0] o_vout_rgb      ;          
 
wire        o_vga_hs ; 
wire        o_vga_vs ;   
wire        o_vga_de ;
wire [23:0] o_vga_rgb;  
wire [23:0] i_vga_rgb;  

wire        clk_hdmi  ;
wire        clk_hdmix5;
wire        hdmi_rstn ;

assign ud_r_0_ud_rclk  =clk_hdmi  ;
assign ud_r_0_ud_rde  = o_vga_de  ;
assign ud_r_0_ud_rvs  = o_vga_vs  ;	
assign i_vga_rgb      =ud_r_0_ud_rdata[23:0];

assign ud_w_0_ud_wclk  =o_vout_clk;	
assign ud_w_0_ud_wdata =o_vout_rgb;	
assign ud_w_0_ud_wde   =o_vout_de ;	
assign ud_w_0_ud_wvs   =o_vout_vs ;	
	
design_1 u_design_1 (
    .DDR3_0_addr    (DDR3_0_addr    ),
    .DDR3_0_ba      (DDR3_0_ba      ),
    .DDR3_0_cas_n   (DDR3_0_cas_n   ),
    .DDR3_0_ck_n    (DDR3_0_ck_n    ),
    .DDR3_0_ck_p    (DDR3_0_ck_p    ),
    .DDR3_0_cke     (DDR3_0_cke     ),
    .DDR3_0_dm      (DDR3_0_dm      ),
    .DDR3_0_dq      (DDR3_0_dq      ),
    .DDR3_0_dqs_n   (DDR3_0_dqs_n   ),
    .DDR3_0_dqs_p   (DDR3_0_dqs_p   ),
    .DDR3_0_odt     (DDR3_0_odt     ),
    .DDR3_0_ras_n   (DDR3_0_ras_n   ),
    .DDR3_0_reset_n (DDR3_0_reset_n ),
    .DDR3_0_we_n    (DDR3_0_we_n    ),
    .ddr3_ok        (ddr3_ok        ),	
    .clk_in1_0      (clk_27m        ),
    .ui_clk_0       (ui_clk_200m    ),
	.rst_n          (rst_n          ),
    .ud_r_0_ud_rclk (ud_r_0_ud_rclk ),
    .ud_r_0_ud_rdata(ud_r_0_ud_rdata),
    .ud_r_0_ud_rde  (ud_r_0_ud_rde  ),
    .ud_r_0_ud_rvs  (ud_r_0_ud_rvs  ),
    .ud_w_0_ud_wclk (ud_w_0_ud_wclk ),
    .ud_w_0_ud_wdata(ud_w_0_ud_wdata),
    .ud_w_0_ud_wde  (ud_w_0_ud_wde  ),
    .ud_w_0_ud_wvs  (ud_w_0_ud_wvs  )	
);	

helai_sdi_driver u_helai_sdi_driver(
    .I_SDI_2_N           (I_SDI_2_N           ),
    .I_SDI_2_P           (I_SDI_2_P           ),	
    .O_SDI_2_N           (),
    .O_SDI_2_P           (),	
    .SDI_GTX_CLK_148_5_N (SDI_GTX_CLK_148_5_N ),    // MGT REFCLKs 148.5 MHz clock
    .SDI_GTX_CLK_148_5_P (SDI_GTX_CLK_148_5_P ),    
    .SDI_GTX_CLK_148_35_P(SDI_GTX_CLK_148_35_P),   // MGT REFCLKs 148.35 MHz clock
    .SDI_GTX_CLK_148_35_N(SDI_GTX_CLK_148_35_N),
	.o_vout_clk          (o_vout_clk          ),
	.o_vout_hs           (o_vout_hs           ),
	.o_vout_vs           (o_vout_vs           ),
	.o_vout_de           (o_vout_de           ),
    .o_vout_rgb          (o_vout_rgb          )	
);

clk_wiz_1 clk_hdmi (
    .clk_hdmi(clk_hdmi),     // output clk_hdmi
    .clk_hdmi_clkx5(clk_hdmix5),     // output clk_hdmi_clkx5
    .locked(hdmi_rstn),       // output locked
    .clk_in1(o_vout_clk)	// input clk_in1
);      

video_timing_control vga(
	.i_clk  (clk_hdmi ),	
	.i_rst_n(hdmi_rstn), 
	.i_rgb  (i_vga_rgb),
	.o_hs   (o_vga_hs ),
	.o_vs   (o_vga_vs ),
	.o_de   (o_vga_de ),
	.o_rgb  (o_vga_rgb)
);

helai_hdmi_out(
	.clk_hdmi     (clk_hdmi   ),
	.clk_hdmix5   (clk_hdmix5 ),
	.reset_n      (hdmi_rstn  ),
	.i_vga_hs     (o_vga_hs   ),
	.i_vga_vs     (o_vga_vs   ),
	.i_vga_de     (o_vga_de   ),	
    .i_vga_rgb    (o_vga_rgb  ),   
    .o_hdmi_clk_p (HDMI_CLK_P ),
    .o_hdmi_clk_n (HDMI_CLK_N ),
    .o_hdmi_data_p(HDMI_DATA_P),
	.o_hdmi_data_n(HDMI_DATA_N)            
);
endmodule

FPGA逻辑资源消耗和功耗如下:
在这里插入图片描述

5、上板调试验证并演示

在这里插入图片描述
输出演示视频如下:

FPGA纯verilog解码SDI视频

6、福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下:
在这里插入图片描述

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

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

相关文章

多元回归分析 | LASSO多输入单输出预测(Matlab完整程序)

多元回归分析 | LASSO多输入单输出预测(Matlab完整程序) 目录 多元回归分析 | LASSO多输入单输出预测(Matlab完整程序)预测结果评价指标基本介绍程序设计预测结果 评价指标 LASSO回归 训练集平均绝对误差MAE:1.7669 训练集平均相对误差MAPE:0.051742 训练集均方根误差MSE…

【ARMv8 编程】ARMv8 指令集介绍

ARMv8 架构中引入的最重要的变化之一是增加了 64 位指令集。该指令集补充了现有的 32 位指令集架构。这种增加提供了对 64 位宽整数寄存器和数据操作的访问,以及使用 64 位长度的内存指针的能力。新指令被称为 A64,以 AArch64 执行状态执行。ARMv8 还包括…

编码的基本概念

本专栏包含信息论与编码的核心知识,按知识点组织,可作为教学或学习的参考。markdown版本已归档至【Github仓库:information-theory】,需要的朋友们自取。或者公众号【AIShareLab】回复 信息论 也可获取。 文章目录信源编码分类前缀…

nginx模块介绍

新编译前,在对应的nginx原编译文件夹 如:nginx-1.23.0 下,要 make clean 清空以前编译的objs文件夹,实际上就是执行了rm objs文件夹。 很多要用到git,先yum install git -y echo-nginx-module 让nginx直接使用echo的…

基于SpringBoot的任务管理三种方式

文章目录前言一,异步任务1.1 无返回值异步任务调用1.2 有返回值异步任务调用二、定时任务2.1 背景介绍2.2 todo三、邮箱任务3.1 todo前言 开发 web 应用时,多数应用都具备任务调度功能,常见的任务包括异步任务、定时任务和邮件任务。我们以数…

springboot+vue企业固定资产管理系统java

资产管理系统可以更加直观的了解到企业资产的使用情况,让企业资产透明化。资产管理系统可以帮助企业标记企业所有的资产,这些资产包括电脑,桌子,椅子等不动资产的标识,以及固定资产的新增,修改,…

渗透测试 | UserInfo信息收集

0x00 免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担…

Leetcode 双指针详解

双指针 双指针顾名思义,就是同时使用两个指针,在序列、链表结构上指向的是位置,在树、图结构中指向的是节点,通过或同向移动,或相向移动来维护、统计信息 在数组的区间问题上,暴力算法的时间复杂度往往是O…

分布式项目-规格参数(13)

【今日成果】: //商品维护模块;其中值得一提的是。商品的介绍全部都做成图片的形式,这样有利于去维护。 商品模块中的页面在created中一开始要对会员等级进行查询操作,访问MemberController中的list接口。 //维护规格参数信息…

【离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计】

离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计一、DWS层设计要点二、DWS层设计分析 - 1d/nd1.DWS层设计一:不考虑用户维度2.DWS层设计二:考虑用户维度2.DWS层设计三 :考虑用户商…

骨骼控制(一)——动画动态节点(AnimDynamics)

文章目录一、引言二、骨骼控制三、UE蓝图中提供的骨骼控制节点——AnimDynamics动画蓝图节点1、什么是AnimDynamics动画蓝图节点①使用盒体计算惯性②使用约束来限制移动2、AnimDynamics节点的几种常用例子①单骨骼模拟②骨骼链模拟 <h2 id1>③群魔乱舞&#xff08;这是错…

YOLOv8之C2f模块——与YOLOv5的C3模块对比

一、源码对比 YOLOv8完整工程代码下载&#xff1a;ultralytics/ultralytic   C2f模块源码在ultralytics/nn/modules.py下&#xff0c;源码如下&#xff1a; class C2f(nn.Module):# CSP Bottleneck with 2 convolutionsdef __init__(self, c1, c2, n1, shortcutFalse, g1, e…

安装kibana 报错/访问不了

安装kibana 报错1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题2&#xff0c;elasticsearch 和kibana版本不一致3&#xff0c;索引问题1&#xff0c;elasticsearch.yaml 和kibana.yaml 配置问题 我的RPM安装的&#xff0c;配置文件都在/etc/ vim /etc/elasticsearc…

【Python知识点桂电版】02组合数据类型

一、序列序列简介序列是指一种包含多项数据的数据结构&#xff0c;分为不可变序列和可变序列。可变序列可修改序列内的元素如列表&#xff0c;二不可变序列一旦建立就不能修改其中的元素&#xff0c;字符串和元组属于不可变序列。列表和元组的创建列表&#xff1a;列表名 [元素…

大学物理期末大题专题训练总结-热学大题

今天下午去找郑老师权老师等去答疑&#xff0c;老师说大题会考查得比较套路&#xff0c;计算不难。明天就要考试了&#xff0c;再把大题常见题型总结一下&#xff0c;热学这块我做完了蓝本的热学题目&#xff0c;发现了如下三种&#xff1a;有关循环过程曲线的&#xff1a;给出…

简历信息提取论文笔记Information Extraction from Resume Documents in PDF Format

标题&#xff1a;Information Extraction from Resume Documents in PDF Format下载地址&#xff1a;https://library.imaging.org/ei/articles/28/17/art00013长度&#xff1a;8页发表时间&#xff1a;2016引用量cite27先读标题、摘要、结论、然后 methods/experiment design,…

大数据NiFi(二十):实时同步MySQL数据到Hive

文章目录 实时同步MySQL数据到Hive 一、开启MySQL的binlog日志 1、登录mysql查看MySQL是否开启binlog日志 2 、开启mysql binlog日志 3、重启mysql 服务&#xff0c;重新查看binlog日志情况 二、​​​​​​​​​​​​​​配置“CaptureChangeMySQL”处理器 1、创建“…

JAVA企业级开发 1.4 Spring_采用Java配置类管理Bean

文章目录一、采用Java配置类管理Bean&#xff08;一&#xff09;打开项目&#xff08;二&#xff09;创建子包&#xff08;三&#xff09;创建杀龙任务类&#xff08;四&#xff09;创建勇敢骑士类&#xff08;五&#xff09;创建Spring配置类&#xff08;六&#xff09;创建测…

STM32单片机之温湿度检测系统(DTH11、OLED、LCD1602)

LCD1602LCD1602引脚第 1 脚: VSS 为电源地 第 2 脚: VDD 接 5V 正电源 第 3 脚: VL 为液晶显示器对比度调整端,接正电源时对比度最弱&#xff0c;接地时对比度最高&#xff0c;对比度过高时会产生“鬼影”&#xff0c;使用时可以通过一个 10K 的电位器调整对比度。 第 4 脚&…

Windows下命令执行绕过技巧总结(渗透测试专用)

一、连接符1、双引号不要求双引号闭合举例&#xff1a;"who"a"mi" //闭合的 "who"a"mi //不闭合的2、圆括号必须在两边&#xff0c;不能包括中间的字符。举例&#xff1a;((whoami))3、^符号&#xff08;转译符号&#xff09;不可以在结尾&…