FPGA硬件jpg解码加速器分享 纯verilog代码实现 提供zynq工程源码和技术支持

1、前言

jpg是一种压缩的图片格式,之所以压缩是为了减小图片所占空间,jpg压缩原理这里不罗嗦,可以自行百度或者b站,大佬讲的比我好,jpg解压缩就是逆向过程,用opencv啥的解压缩就是一句话的事儿,但对于fpga硬件来说就是大型工程了。

本设计使用zynq7100位平台,将jpg图片的c语言数组写入PS侧DDR3中缓存作为jpg解码器的输入,使用自研的AXI4控制器从DDR3中读取出jpg图片数据,并转换为AXIS数据流送入jpg解码器解码为rgb数据输出,至此,jpg解码实际已经完成,但为了输出显示验证解码的效果,再加上基于FDMA的图像缓存架构将jpg解码后的rgb数据输出显示器显示,可以直观的查看显示器的输出与原始jpg图片的差异,以验证我们设计的正确性。。。。

本文详细描述了zynq7100位平台验证jpg解码器并将解码后的rgb数据输出显示器显示的设计方案,工程代码编译通过后上板调试验证,文章末尾有演示视频,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;

2、JPG解码器详解

JPG解码器是本设计的核心,其他设计都是围绕本模块来设计,目的就是为了验证本模块的正确性;
本JPG解码器具有以下特征:
1:纯verilog代码实现,不含有任何IP核;
2:移植性天花板,由于采用纯verilog代码实现,可在Xilinx、Altera和国产FPGA (比如紫光同创、安路)等之间任意移植;
3:32bit的AXI4-Stream数据流输入接口,可处理大批量数据;
4:支持任意分辨率jpg图片解码;
5:支持YUV4:4:4、YUV4:2:0色度采样输入;
6:支持固定的标准的霍夫曼解码(减少逻辑资源的使用和更快速解码);
7:支持动态霍夫曼解码(使用更多的逻辑资源和更慢速解码);
8:动态DQT;
9:输出24bit的RGB8:88格式,同时输出解码后的图片宽和高数据;
10:消耗逻辑资源少,具体如下:
在这里插入图片描述
jpg解码器模块设计框图如下:
在这里插入图片描述
解码过程就是编码过程的逆过程,原理可以百度一下或者csdn搜一下,本模块就是把用c语言或者c++实现的软件解码方式用verilog的硬件解码方式实现了,由于FPGA的并行性,所以解码速度更快,达到加速的目的。。。

3、设计思路和架构

设计思路和架构如下:
在这里插入图片描述
总体流程:
第一步:
下载一张jpg图片,用Matlab等工具将jpg图片转为c语言数组,提供的vivado工程中已包含此文件;
第二步:
用SDK将jpg图片c语言数组拷贝到PS侧DDR3中缓存,作为jpg解码器的输入源;
第三步:
AXI4主机控制器和AXI4-Stream主机控制器负责从PS侧DDR3中读取jpg数据,输出AXI4-Stream数据流给到jpg解码器;
第四步:
jpg解码器将AXI4-Stream格式的jpg数据解码为24bit的RGB数据输出,一同输出图片宽个高信息;至此,jpg解码实际已经完成,但为了输出显示验证解码的效果,再加上基于FDMA的图像缓存架构将jpg解码后的rgb数据输出显示器显示,可以直观的查看显示器的输出与原始jpg图片的差异,以验证我们设计的正确性。。。。
第五步:
使用FDMA数据缓存架构将解码后的RGB数据缓存至PS侧DDR3后再读出,这里做缓存的原因是做数据跨时钟处理,jpg解码后的rgb数据时钟是100M,而HDMI输出的像素时钟是148.5M。。。关于FDMA数据缓存架构,可以参考我之前写的文章直接点击此处查看
第六步:
HDMI输出分辨率使用1920x1080@60Hz,只要jpg图片分辨率小于1920x1080均可在此背景下输出,屏幕只会输出有效的jpg图片,其他区域为黑色,这也是我的一大原创。。。需要解码显示更大jpg图片分辨率的朋友可以修改输出VGA时序,比如改为4K分辨率,则可显示1920x1080的图片了。
HDMI发送没有使用HPY芯片,而是使用纯verilog实现的HDMI发送驱动,关于这一点,可以参考我之前写的文章直接点击此处查看

4、vivado工程详解

开发板:Xilinx zynq7100开发板;
开发环境:vivado2019.1;
输入:jpg图片;
输出:HDMI显示;

工程Block Design如下:
在这里插入图片描述
综合后的工程代码架构如下:
在这里插入图片描述
jpg解码器源码如下:
在这里插入图片描述
总工程师的资源消耗和功耗预估如下:
注意:这里是整个工程的资源消耗,并非jpg解码器;
在这里插入图片描述
SDK源码架构如下:
在这里插入图片描述

5、上板调试验证

开发板如下:
在这里插入图片描述

程序调试方法

需要你的板子有个HDMI输出接口
第一步:
编译,打开SDK,并进行debug单步调试,如下:
在这里插入图片描述
在这里插入图片描述
第二步:
选择你要解码输出的jpg图片分辨率,为了深度测试jpg解码器的性能,我这里设置了7种不同分辨率的jpg图片,分别如下:
jpg图片分辨率:1920x1080;
jpg图片分辨率:1280x720;
jpg图片分辨率:800x800;
jpg图片分辨率:800x600;
jpg图片分辨率:606x530;
jpg图片分辨率:474x458;
jpg图片分辨率:361x458;
在这里插入图片描述
下面以1920x1080图片解码为例,首先取消上图中//WR_pic_1920x1080();前面的//,如此就选择了解码输出1920x1080图片,随后按照第一步开始单步debug,当dubug到while(1)死循环里面时,多点几次,让程序在while(1)里面多转几圈,屏幕就会出现RGB图片输出了,while(1)里面的代码作用是产生触发信号开启jpg解码器工作。。。

下面看输出效果:
解码jpg图片分辨率1920x1080的输出:
在这里插入图片描述
在这里插入图片描述
解码jpg图片分辨率1280x720的输出:
在这里插入图片描述
在这里插入图片描述
解码jpg图片分辨率800x800的输出:
在这里插入图片描述
在这里插入图片描述
解码jpg图片分辨率800x600的输出:
在这里插入图片描述

在这里插入图片描述
解码jpg图片分辨率606x530的输出:
在这里插入图片描述
在这里插入图片描述
解码jpg图片分辨率606x530的输出:
在这里插入图片描述
在这里插入图片描述
解码jpg图片分辨率606x530的输出:
在这里插入图片描述
在这里插入图片描述
下面看视频演示:

fpga-jpg

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

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

猜你喜欢

转载自blog.csdn.net/qq_41667729/article/details/129907610