【ZYNQ入门】第九篇、双帧缓存的原理

目录

第一部分、基础知识

1、HDMI视频撕裂的原理

2、双帧缓存的原理

第二部分、代码设计原理

1、AXI_HP_WR模块

2、AXI_HP_RD模块

[3、Block design设计](#3、Block design设计)

第三部分、总结

1、写在最后

2、更多文章


第一部分、基础知识

1、HDMI视频撕裂的原理

在调试摄像头的时候,摄像头采集的图像的分辨率为2200*1125@30Hz ,因此摄像头采集图像的速率为30帧/s而显示器的分辨率为1920*1080@60Hz ,因此显示器的显示速率为60帧/s。那么很明显,显示器得显示速率是大于摄像头采集图像的速率的

当DDR采用单帧缓存的方式来缓存图像时,那么就存在一个问题,**那就是读数据存在一个超越的过程。**当摄像头前的物体在移动时,就会出现一条撕裂线,导致这条撕裂线的原因就是因为显示器上半帧显示的图像为新图,下半帧显示的图像为旧图。

具体的撕裂效果如下:

|-------------|
| 单帧缓存带来的撕裂现象 |

2、双帧缓存的原理

下图就是双帧缓存的原理流程图,**核心思想就是:****某一帧图像会被读两次。**例如:当前A帧读完了,但是B帧还没有写完,那么HDMI就再显示一遍A帧,当B帧这个时候写完了,来写A帧的时候,也不会发生冲突,因为读取的速度比写入的速度快。

没有学这些东西的时候,觉得好高级,学了之后发现哦,原来是这样啊。

第二部分、代码设计原理

由上面的原理图可知,只需要在AXI HP口的写模块内部定义一个frame_flag,当写帧A的时候,就拉低,当写帧B的时候,就拉高,一直循环 。接着将frame_flag导出到AXI HP口的读模块。在读模块内根据frame_flag信号的高低,来确定要读取帧的地址。

1、AXI_HP_WR模块

AXI_HP_WR模块,用来输出frame_flag。

rust 复制代码
	//Address  //加入了双帧buffer控制代码
	always @(posedge M_AXI_ACLK) begin
		if (M_AXI_ARESETN == 1'b0) begin
			axi_awaddr <= 'd0;
			frame_flag <= 1'b1;//刚上电,写A区域,但是一开始需要读A区域(会出现帧不同步,后面就不会了)
		end
		//区域B 1920*1080*4-256*8 = 16586752
		else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1 && axi_awaddr == 'd16586752) begin
			axi_awaddr <= 'd0;//初始0地址,A区域开始地址 
			frame_flag <= 1'b0;//写A区域的时候为低电平 
		end	
		//区域A 1920*1080*4-256*8 = 8292352
		else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1 && axi_awaddr == 'd8292352) begin
			axi_awaddr <= 'd8294400;//B区域开始地址1920*1080*4
			frame_flag <= 1'b1;//写B区域的时候为高电平    
		end		
		else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1) begin
			axi_awaddr <= axi_awaddr + 'd2048;
		end
	end

2、AXI_HP_RD模块

AXI_HP_RD模块,判断frame_flag。

rust 复制代码
	//frame flag for double buffer
	always @(posedge M_AXI_ACLK) begin
	  if(M_AXI_ARESETN == 1'b0) begin 
	      axi_araddr <= 'd0;
	  end
	  //A帧最后一个突发长度
	  else if (axi_arvalid == 1'b1 && M_AXI_ARREADY == 1'b1 && axi_araddr == 'd8292352) begin
	  	//对frame_flag进行判断
	  	if(frame_flag == 1'b0) begin
	  		axi_araddr <= 'd8294400;
	  	end
	  	else begin
	  		axi_araddr <= 'd0;
	  	end
	  end
	  //B帧最后一个突发长度
	  else if (axi_arvalid == 1'b1 && M_AXI_ARREADY == 1'b1 && axi_araddr == 'd16586752) begin
	  	//对frame_flag进行判断
	  	if(frame_flag == 1'b0) begin
	  		axi_araddr <= 'd8294400;
	  	end
	  	else begin
	  		axi_araddr <= 'd0;
	  	end
	  end
	  
	  else if (axi_arvalid == 1'b1 && M_AXI_ARREADY == 1'b1) begin
	      axi_araddr <= axi_araddr + 'd2048;
	  end
	end

3、Block design设计

AXI HP口的写数据通道和读数据通道是分开,因此这里拆分为两个模块。

第三部分、总结

1、写在最后

这篇博客是我在调试摄像头显示的时候,记录的笔记。关于双帧缓存的实现还是比较简单的,所以文章比较简短。

关于AXI_HP接口的基本知识,请大家参考这篇文章:【ZYNQ入门】第五篇、AXI HP口读写数据原理-CSDN博客

我学习的途径是:《V3学院的视频课程》。

我个人觉得如果大家是那种坐得住,爱调试,心态比较好的,其实你会发现搞FPGA还真的挺有意思的。

2、更多文章

QQ交流群聊号码1020775171,有疑问的小伙伴可以加入哦🤗🤗🤗

本专栏有很多我个人总结的比较好的文章,希望对你开发有帮助:FPGA的学习之旅_大屁桃的博客-CSDN博客

相关推荐
nuoxin1146 小时前
GSV1011-富利威-HDMI芯片选型
arm开发·驱动开发·fpga开发·ffmpeg·射频工程
ChipCamp6 小时前
FPGA开发入门----1. Mux的三种写法,RTL的认知大提升!
fpga开发·时序逻辑·组合逻辑
XINVRY-FPGA1 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga
9527华安2 天前
国产安路FPGA开发设计培训课程,提供开发板+工程源码+视频教程+技术支持
fpga开发·fpga·安路·视频教程·培训·安路fpga
UVM_ERROR2 天前
硬件设计实战:解决Valid单拍采样失效问题(附非阻塞赋值与时序对齐核心要点)
驱动开发·fpga开发·github·芯片
brave and determined2 天前
可编程逻辑器件学习(day36):从沙粒到智能核心:芯片设计、制造与封装的万字全景解析
fpga开发·制造·verilog·fpga·芯片设计·硬件设计·芯片制造
步达硬件3 天前
【FPGA】FPGA开发流程
fpga开发
我爱C编程3 天前
【仿真测试】基于FPGA的完整16QAM通信链路实现,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
fpga开发·16qam·帧同步·卷积编码·viterbi译码·维特比译码·频偏锁定
s09071364 天前
ZYNQ DMA to UDP 数据传输系统设计文档
网络协议·fpga开发·udp
燎原星火*4 天前
QSPI IP核 基本参数
fpga开发