小言_互联网的博客

FPGA精简版UDP协议实现板间网线传输视频,提供3套工程源码

354人阅读  评论(0)

1.FPGA精简版UDP介绍

精简版UDP协议是一种资源占用少,不限FPGA硬件平台,纯Verilog代码实现的UDP通信方案,经本人反复验证,稳定性很高,关于精简版UDP请参考我之前写的文章点击查看:精简版UDP

2.网线板间视频传输—精简版UDP再次精简

查看我之前写的文章点击查看:精简版UDP后,应该会知道整个UDP方案如下:

但对于板件视频传输而言,ARP协议是不需要的,我们只需用到串并转换和UDP收发即可,再次精简后的UDP架构如下:

3.网线板间视频传输—实现方案

总体方案如下图:

下面解释一下图中的关系:
开发板1:视频发送
视频源:这里是OV5640摄像头,当然,其他视频也可以;
数据采集:OV5640摄像头输出的是RGB565格式图像,这里做数据采集,并生成vs、hs、de等时序;
FDMA视频三帧缓存通路:这部分在UDP发送中并没有实际意义,之所以缓存并输出是为了验证视频采集的正确性,也为了和接收板卡的输出进行比较,看传输是否正确,在验证正确后,可删除此部分,关于FDMA视频三帧缓存通路请参考我之前写的文章点击查看:FDMA视频三帧缓存架构
UDP编码:将摄像头采集数据进行数据编码,为UDP发送做准备;
这里的做准备有如下几层意思:
1、数据位宽的转换:RGB565的16bit数据转换到32bit的UDP数据位宽;
2、时钟域的转换,OV5640输出时钟大概30M左右,转换到UDP千兆模式的125M;
3、数据组包:UDP一次传输一行视频数据,称为一个UDP包,每个UDP包都好包含包头和数据段;包头包括固定的4字节帧头和视频行号,一个UDP包组成如下:
UDP发送:使用精简版UDP再精简实现,关于精简版UDP请参考我之前写的文章点击查看:精简版UDP
PHY1:也就是网络PHY芯片,这里不再多讲;

图中的字节数需要好好理解一下;

开发板2:视频接收
PHY2:也就是网络PHY芯片,这里不再多讲;
UDP接收:使用精简版UDP再精简实现,关于精简版UDP请参考我之前写的文章点击查看:精简版UDP
UDP解码:将接收到的UDP数据解码为视频数据,并生成vs、hs、de等时序;
这里的解码有如下几层意思:
1、解包,丢弃帧头,保留有效数据;
2、数据位宽的转换:32bit的UDP数据位宽转换到RGB565的16bit数据;
FDMA视频三帧缓存通路:这部分实现将接收到的UDP视频数据输出到显示器上显示,关于FDMA视频三帧缓存通路请参考我之前写的文章点击查看:FDMA视频三帧缓存架构

4.网线板间视频传输—发送端方案

发送端主要实现的功能上面已经讲了,这里主要讲如何实现,很显然,只需一个fifo即可;
发送端顶层接口部分如下:

module ov5640_tx_rj45(
    input              gmii_tx_clk     ,	//发送端时钟	
	input              cam_pclk        ,	//摄像头时钟
    input              rst_n           ,	//系统复位信号,低电平有效  	
    input              tx_done         ,	//以太网发送完成信号
    input              tx_req          ,	//读数据请求信号 	
    output             tx_start_en     ,	//以太网开始发送信号
    output     [31:0]  tx_data         ,	//以太网待发送数据                    
    input              cmos_frame_vsync,    //输入场信号
	input              cmos_frame_href ,    //输入行信号
    input              cmos_frame_valid,    //输入数据有效信号
    input      [15:0]  cmos_data        	//输入数据
    );

关键的部分是数据的组包和fifo读使能的控制,总体思路就是:fifo先缓存一行视频数据,存满后通知UDP来读,然后发起一次UDP发送,就这么简单;
组包部分关键代码如下:

//产生tx端发送数据
always@(posedge gmii_tx_clk)begin
	if(!rst_n || frame_flag_t) tx_data <= 0;
	else if(tx_req && cnt_tx_req == 0) tx_data <= {
   16'ha151,cnt_v};		
	else if(tx_rd_en) tx_data <= tx_rd_data;		
    else tx_data <= tx_data;		
end	

5.网线板间视频传输—接收端方案

接收端是发送端的逆过程,实现方法依然是一个fifo搞定,不同的是接收端不需要跨时钟域,因为直接把接收时钟作为ddr缓存的写入时钟;
接收端顶层接口部分如下:

module rj45_rx_ov5640(
    input         gmii_rx_clk ,	//接受端时钟	
    input         rst_n       ,	//系统复位信号,低电平有效  	
    input         rec_pkt_done,	//以太网单包数据接收完成信号
    input         rec_en      ,	//以太网接收的数据使能信号
    input  [31:0] rec_data    ,	//以太网接收的数据  
	output        vout_vs     ,	//输出场vs
	output        vout_de     ,	//输出场de
	output [15:0] vout_rgb565	//输出场rgb565 
    );

解包部分关键代码如下:

//产生网络帧帧头
always@(posedge gmii_rx_clk)begin
	if(!rst_n) rx_frame_flag <= 0;
    else if(rec_en_d1 && (pkt_head == 32'ha1510000) && (cnt_rec_en == 1)) rx_frame_flag <= 1;
	else if(cnt_rx_frame_flag >= 100) rx_frame_flag <= 0;
    else rx_frame_flag <= rx_frame_flag;	
end

6.工程1介绍—Artix7(RTL8211)双网口环回

开发板:Artix7开发板;
网络PHY:RTL8211;
开发环境:vivado2019.1;
输入:OV5640摄像头,720P,RGB565;
输出:网线,HDMI显示器;
Artix7开发板有2个网口,PHY均为RTL8211,用网线连接2个网口实现视频回环收发;
工程BD如下:

工程代码架构如下:

7.工程2介绍—Artix7发送—>Kintex7(B50610)接收

发送端:
开发板:Artix7开发板;
网络PHY:RTL8211;
开发环境:vivado2019.1;
输入:OV5640摄像头,720P,RGB565;
输出:网线;
接收端:
开发板:Kintex7开发板;
网络PHY:B50610;
开发环境:vivado2019.1;
输入:网线;
输出:HDMI显示器;
整个架构需要两块板子,一根网线,当然也有两个工程,这里就不具体展示了,截图太多手软了;

8.工程3介绍—Kintex7发送—>Artix7接收

发送端:
开发板:Kintex7开发板;
网络PHY:B50610;
开发环境:vivado2019.1;
输入:OV5640摄像头,720P,RGB565;
输出:网线
接收端:
开发板:Artix7开发板;
网络PHY:RTL8211;
开发环境:vivado2019.1
输入:网线;
输出:HDMI显示器;
整个架构需要两块板子,一根网线,当然也有两个工程,这里就不具体展示了,截图太多手软了;

9.板极调试验证

回环工程如图:

板间收发连接如图:

再来个视频演示:A7发送K7接收的演示;

udp板间视频传输

10.福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料如下:获取方式:私。




转载:https://blog.csdn.net/qq_41667729/article/details/127967851
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场