【FPGA项目】图像采集及显示(2)详细设计方案

该博客详细介绍了FPGA图像采集及显示的设计方案,包括视频流采集、DDR3缓存控制、FIFO设计和VGA显示器驱动。通过MT9V034传感器采集VGA图像数据,利用DDR3缓存和FIFO同步不同时钟域,最终通过VGA接口显示图像。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、视频流采集设计

二、DDR3缓存控制

三、FIFO 设计

四、VGA显示器驱动设计

五、代码


前言

上文描述了系统框图,本篇则对各个模块进行详细描述:

一、视频流采集设计

MT9V034输出VGA(752*480像素)并行数据视频流协议的时序波形如下:

场同步信号FRAME_VALID:为高时,表示一帧图像;

行同步信号LINE_VALID:为高时,表示数据是有效的视频流。

        即:从FRAME_VALID拉高开始,在LINE_VALID为高电平期间依次传输的是第1行、第2行、第3行...、第480行数据,每行数据包含了752像素的灰度信息。

并行数据视频流时序如下:

        图像采集时,先用一个异步FIFO来同步外部输入的数据和FPGA内部逻辑。每一帧新图像开始前FIFP进行一次清空。在FIFO的读端口,一个简单的FIFP读控制状态机会判定当数据≥16时,就连续读出者16个数据,送到ddr_cache.v的DDR3写缓存FIFO中。

        使能信号image_ddr3_wren、清除信号image_ddr3_clr、图像数据image_ddr3_wrdb是送到后续模块写入DDR3中的视频流数据。

        图像采集框图如下:

二、DDR3缓存控制

        ddr3_cache.v模块设计两个FIFO,WR_FIFO用于缓存写入的图像数据,RD_FIFO用于缓存从DDR3读出的图像数据。DDR不就是缓存吗,为什么需要FIFO?因为DDR需要刷新,控制器输出的有效信号并不一直为高,所以要FIFO存一下,才能保证数据不丢失。而DDR3的读写控制在同一时刻不能并行,所以需要DDR3读写仲裁控制逻辑。读写相关地址、控制信号都需要分别时序。

DDR3读写状态切换如下:

        空闲状态SIDLE,判断读数据缓存FIFO或写数据FIFO的数据量,以确定是否进入读数据状态SRDDB或写数据状态SWRDB。在SRDDB或SWDDB下,发起DDR3的读写请求和相应接口时序,完成固定的burst数据量读写后,进入状态SSTOP,然后回到IDLE状态。

DDR3 IP设计,详见另外博客:Xilinx FPGA平台DDR3设计保姆式教程(汇总篇)——看这一篇就够了-CSDN博客

三、FIFO 设计

整个设计工程中,配置使用了 3个异步FIFOIDC FIFO)实现了以下3个作用。

  1. 实现不同时钟域的切换。如图像同步时钟 image_sensor_pclk通过 fifo_generator_2转换到 FPGA 内部时钟 clk_50m,时钟 clk_50m 则通过 fifo_generator_0 和 fifo _generator_1转换到 DDR3 Controller IP 的同步时钟 ui_clk。
  2. 对数据进行缓存,写入是慢时钟域的零散数据,读出是快时钟域的成块数据。例如fifo_generator_2的输入时钟要慢于读出的 50MHz时钟,但经过 FIFO 缓存,数据以每 16个像素为单位读出。
  3. 数据位宽的转换。例如 fifo_generator_0和 fifo_generator_1这两个 FIFO,在clk _50m时钟一侧,均是 16 位宽,而在 ui_clk 时钟一侧,均是 128位宽与DDR3Controller IP 实现数据交互。

 工程中的3个 FIFO之间的数据交互和所在模块关系如下图所示。单纯从设计角度看,fifo_generator_2和 fifo_generator_1这两个 FIFO 是可以只使用后者替代,这里之所以保留了两级FIFO缓存,是为了后续的工程中,方便在两级 FIFO之间的逻辑代码中添加一些图像处理功能。

FIFO IP的例化就不展开了,参见《PG057》

四、VGA显示器驱动设计

        FPGA开发板通过PMODE接口外接VGA显示模块(板载ADV7123芯片),可实现VGA显示器的显示控制。本实例要将8位的灰度图像显示在VGA显示器上。

ADV7125内部功能框图如下所示:

下图展示了显示驱动接口:

VGA显示器的数据同步使用行同步信号HSYNC和场同步信号VSYNC即可实现。

而在FPGA内部,使用图中示意的DE信号脉冲高电平,送出有效的RGB数据。

为了便于实际驱动计数器的时序产生,还是需要对行和列计数器的同步脉冲、后沿脉冲、显示脉冲、前沿脉冲做定义,参数表如下:

传输数据不可能一下子全部送过去,只能一个像素点一个像素点的送图像数据,从方向来看,就是从左到右(x轴),从上到下(y轴):

        因此,代码中定义了两个12位的计数器,即x轴计数器xcnt和y轴计数器 ycnt。xcnt随主时钟不停地计数, ycnt 在xcnt 计数器完成一个周期计数时才会递增计数,它也有自己的计数周期。xcnt 和 ycnt 的计数周期值都是由前面的参数定义好的。

        实际的数据传输方式不仅仅只有x轴和y轴的有效显示图像的数据,而是在每一行或每一场(即一个完整的图像帧)的开始和结束都有一些空闲的时间,这个时间内的数据不显示在屏幕上,可以用来产生一些同步信号,避免行、场的错乱。

        X₋cnt和y₋cnt两个计数器产生一个二维图像的有效显示区域,结合同步脉冲的判断,产生同步信号、vga₋hsy vga₋vsy和 vga_vsy。有效显示区域的图像数据从DDR3中读取,对应的图像就是 MT9V034采集到的图像。控制接口上,这个模块输出lcd_rfclr信号作为每个图像帧的同步信号,或者称为复位信号,在每个有效显示图像开始前,这个信号都会拉高一段时间,ddr3₋cache.v模块可以用这个信号实现 FIFO的复位,以及对应的控制信号的复位。读数据请求信号 lcd_rfreq会产生连续的 640×480个时钟周期的高电平,用于读取 DDR3中的图像数据。8位数据总线 lcd_rfdb则在每个读数据请求信号 lcd_rfreq拉高后有效(读取 FIFO会有1个时钟周期的延时),对应数据送到液晶屏显示。

五、代码

        本篇内容都是来自【特权同学】的工程,完整代码路径如下(免费,0积分):(刚上传,审核后会在我的主页—资源)

        图像采集其实挺简单的,关注接收时序以及内部缓存的逻辑设计就好,下一篇我们做个总结,聊聊项目设计的一些重点内容和调试小技巧。

        由于最近在搞其他的,所以图像采集就用(特权同学)的工程收个尾吧,暂时不展开了,见谅。(本篇免费,侵权删)

后记

        因为最近在学习RISC-V的一些东西,所以后续准备先手搓一个简易的MPU练练手;(其他一些FPGA项目暂时先放放)然后记录一下RISC-V CPU蜂鸟e203的整体学习,以及移植到FPGA跑跑程序的整个过程。

        顺便提一下,CPU设计真的是芯片设计的集大成者,博大精深,知识点又多又细又深入,头皮发麻,什么时候才能成长为系统架构师 = _=

        咱们下期见~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

子墨祭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值