LCD显示技术完全指南:原理·制造·驱动·FPGA实现之点屏三

篇10:不用DDR也能玩视频------FPGA无帧缓存显示方案全解析

上一篇我们讲了用DDR做帧缓冲,性能强大,但不是每个项目都负担得起DDR的成本和布线复杂度。

如果你只需要显示简单的UI、传感器数据、或者来自低速接口的图像(如SPI摄像头、UART图片),或者你用的FPGA资源紧张(没有DDR控制器,也不想外挂DRAM),那么无DDR方案 可能是更务实的选择。

这一篇,我会带你分析在不使用DDR的情况下,FPGA如何实现视频显示,包括几种可行的架构、各自的资源要求、开发中的坑,以及什么时候该放弃这个方案。


一、为什么考虑"无DDR"?

优势 说明
成本降低 省去DDR芯片、PCB走线、终端电阻,BOM减少2~5美元
PCB简化 不需要DDR的等长布线、参考平面、VREF,4层板可能变2层板
功耗降低 DDR3/DDR4的IO功耗(约每GB/s 100~200mW)和省去PHY功耗
启动快 无需DDR初始化、训练(training)过程,上电即用
可靠性高 减少一颗外部芯片,减少失效点
劣势 说明
分辨率受限 内部BRAM容量有限,无法缓存完整高清帧
图像内容受限 不能存储复杂的全帧图像,只能显示简单图案或实时流
数据源必须同步 如果没有帧缓冲,数据源速率必须精确匹配屏幕刷新率,否则撕裂

适用场景

  • 低分辨率显示(≤ 480×272)
  • 仪表盘、波形、字符、简单动画(无需复杂图片)
  • 摄像头实时直通显示(不存储,只做格式转换)
  • 工业控制HMI(静态界面+局部刷新)

二、无DDR显示方案的三种主流架构

架构A:BRAM完整帧缓冲(小分辨率)

原理 :用FPGA内部BRAM存储完整的一帧图像,显示控制器从BRAM读取,数据源(如CPU、UART、SPI Flash)写入BRAM。

容量计算

分辨率 色深 帧缓冲大小 BRAM块数(36Kb/块) 典型FPGA可行性
320×240 RGB565 320×240×16 = 1,228,800 bit ≈ 34 任何小FPGA均可
480×272 RGB565 480×272×16 ≈ 2,088,960 bit ≈ 58 Artix-7 35T有50块,勉强;50T以上可
640×480 RGB565 640×480×16 = 4,915,200 bit ≈ 137 需中规模FPGA(如A200T)
800×480 RGB565 6,144,000 bit ≈ 171 大容量FPGA,成本不划算

优缺点

  • ✅ 简单,显示控制器与数据源完全异步
  • ✅ 支持任意图像内容(因为完整存储)
  • ❌ 分辨率上限低(通常≤480×272)
  • ❌ BRAM占用量大,影响其他逻辑

适用 :静态图片、简单GUI、字符显示。

架构B:线缓存 + 实时流处理(无帧缓冲)

原理 :不存储完整帧,数据源实时向FPGA发送像素流,FPGA只缓存少量行(line buffer)用于时序重整或格式转换,然后直接输出到屏幕。

典型应用

  • 摄像头(如OV7670、MT9M001)直接驱动屏幕
  • 视频解码器(如ADV7180)输出ITU-R BT.656转RGB

关键挑战 :数据源的行/场同步必须与屏幕时序完全匹配(或通过FIFO异步桥接)。如果数据源输出速率不等于屏幕PCLK,就需要 速率匹配

速率匹配方法

  1. 源时钟直接作为PCLK :如果摄像头输出PCLK与屏幕要求的PCLK频率一致,可以直接用。但多数情况下不一致。
  2. 异步FIFO + 行消隐补偿 :将数据源像素写入FIFO,屏幕控制器从FIFO读取。只要平均写入速率 ≥ 读取速率,且FIFO深度足够覆盖瞬时波动,就能正常工作。行消隐期提供额外的补偿时间。

FIFO深度计算 (示例):

  • 源像素时钟 = 12MHz,有效像素率 ≈ 10MP/s
  • 屏幕PCLK = 25MHz,有效像素率 = 800×480×60 ≈ 23MP/s
  • 写入速率 < 读取速率 → FIFO会空,不行。必须 源速率 ≥ 屏幕有效速率 ,否则丢帧。

实际可用 :当源速率略低于屏幕刷新率时,可以在屏幕消隐期暂停读取,让FIFO积累数据。但会导致帧率降低(屏幕出现重复帧或卡顿)。

优缺点

  • ✅ 极低延迟(通常只有几行延迟)
  • ✅ 几乎不占BRAM(只需几行缓存,几十KB)
  • ✅ 支持高分辨率(只要源能提供足够带宽)
  • ❌ 数据源必须与屏幕时序强耦合,难以处理异步数据源(如网络图片)
  • ❌ 不能实现图像叠加、缩放等复杂处理

适用 :摄像头实时监控、视频直通。

架构C:外部SPI PSRAM / SRAM作为帧缓冲

原理 :外挂一颗便宜的非DDR存储器,如 SPI PSRAM (如APS6404L-3SQR,64Mbit,~$1.5)或 并行SRAM (如IS61LV25616,但价格高)。FPGA通过SPI或并行接口读写,作为帧缓冲。

SPI PSRAM特点

  • 容量大(可达256Mbit),价格低
  • 接口简单(SPI,4~6根线)
  • 带宽有限(SPI时钟通常50~100MHz,理论最大50MB/s)
  • 随机访问延迟大(SPI命令+等待)

带宽验证 (以800×480 RGB565为例):

  • 每帧数据量 = 800×480×2 = 768KB
  • 60Hz → 需要读取带宽 768KB × 60 = 46.08 MB/s
  • SPI PSRAM @ 100MHz(双倍数据率?普通SPI单沿)最大约12.5MB/s(单线)或50MB/s(四线QSPI)。四线QSPI勉强够用。

实现注意

  • 必须使用突发读取模式,利用PSRAM的连续地址访问特性
  • 需要读缓存FIFO,防止PSRAM延迟导致下溢
  • 写操作(数据源更新)会占用带宽,需要合理安排时序(如利用消隐期写入)

优缺点

  • ✅ 成本低于DDR,布线简单(SPI只需少量IO)
  • ✅ 支持中等分辨率(800×480)和复杂图像
  • ❌ 带宽紧张,高分辨率(≥1024×600)可能不够
  • ❌ 需要额外的SPI控制器和缓存逻辑

适用 :成本敏感的嵌入式显示,分辨率不超过WVGA。


三、系统要求与开发注意事项

3.1 数据源带宽匹配

无论哪种架构,无DDR方案最核心的问题是 数据源速率与屏幕刷新率的匹配

公式

text

复制代码
源有效数据速率 ≥ 屏幕有效数据速率

其中有效数据速率 = 分辨率 × 色深 × 帧率。

如果不满足,必须引入帧缓冲(哪怕是小容量的BRAM)来解耦。否则屏幕会出现反复撕裂或闪屏。

工程建议 :在设计初期计算理论速率,留出20%余量。例如屏幕需要46MB/s,源应能提供至少55MB/s。

3.2 时序约束与跨时钟域

无DDR方案中往往存在多个时钟域:

  • 数据源时钟(如摄像头PCLK)
  • 屏幕像素时钟(PCLK)
  • 内部处理时钟(可能更高,用于插值或色彩转换)

跨时钟域处理

  • 异步FIFO是最可靠的方法,深度根据最大时钟差和突发长度计算。
  • 对于单bit控制信号(如行同步),使用两级寄存器同步 + 边沿检测。

注意 :不要试图用组合逻辑直接连接不同时钟域的FIFO读写指针,会引入亚稳态。

3.3 行缓存(Line Buffer)的设计

在实时流处理中,常见操作是缓存N行数据用于:

  • 色彩空间转换(如YUV422转RGB需要两行)
  • 图像缩放(双线性插值需要2~4行)
  • 去隔行(需要两场)

实现方法 :使用BRAM配置为简单的 移位寄存器 (SHIFT_REG)或 双端口RAM ,每次写入一行,读取前一行。

资源估算 :一行800像素RGB565 = 800×16 = 12.8Kb。缓存2行需要25.6Kb,不足一块BRAM(36Kb),可以容纳。缓存4行需51.2Kb,需2块BRAM。

3.4 FIFO深度设计

异步FIFO用于连接数据源和屏幕控制器时,深度必须满足:

  • 最大写入突发长度(如摄像头一行有效像素)
  • 最大读取连续时间(屏幕一行有效像素)
  • 最坏情况下的时钟相位差

经验公式

text

复制代码
FIFO深度 ≥ (写入峰值速率 - 读取峰值速率) × 最大突发时间 + 安全边际

对于摄像头到屏幕的直接直通,通常 一行深度 (如800像素)足够,因为行消隐期可以清空或填充FIFO。

3.5 屏幕消隐期的利用

在无DDR方案中,消隐期是宝贵的时间窗口,可以用于:

  • 更新BRAM帧缓冲(如果使用架构A)
  • 从SPI PSRAM预取下一行数据(架构C)
  • 发送控制命令(如摄像头寄存器配置)

实现技巧 :利用VSYNC或HSYNC中断,触发DMA或状态机在消隐期执行操作。


四、实战案例:用BRAM显示SPI Flash中的图片(480×272)

4.1 系统概述

  • FPGA:Cyclone IV EP4CE10(约 46 块 M9K BRAM,每块9Kb)
  • 屏幕:480×272,RGB565(16位色)
  • 图片存储:SPI Flash(W25Q64),存放一张480×272的RGB565原始数据(约255KB)
  • 流程:上电后,FPGA从SPI Flash读取图片数据,写入BRAM帧缓冲,然后显示控制器循环显示。

4.2 资源评估

BRAM需求:480×272×16 = 2,088,960 bits = 255KB。

Cyclone IV M9K块大小 9Kb = 1.125KB,需要 255 / 1.125 ≈ 227 块。而EP4CE10只有 46 块! 不够

解决方案

  • 降低分辨率:320×240 RGB565 = 150KB,需133块,仍然不够。
  • 使用更高密度FPGA(如EP4CE22有 66 块,还是不够)。
  • 改用压缩图片(如RLE),运行时解压到BRAM。但需要增加解压逻辑。
  • 实际选择 :改用更小分辨率(如240×160)或改用外部SRAM。

结论 :对于480×272 RGB565,大部分低端FPGA的BRAM不足以做完整帧缓冲。这是架构A的主要限制。

4.3 可行的低端实现:240×160 RGB565

  • 帧缓冲大小 = 240×160×16 = 614,400 bit = 75KB
  • BRAM块数 ≈ 75 / 1.125 ≈ 67 块(EP4CE10只有46块,仍然不够!因为M9K是9Kb,实际可用约46×9Kb=414Kb=51.75KB,只能支持 51.75KB / 2字节/像素 = 25875像素,约160×160 分辨率)。

所以, EP4CE10 最大无压缩帧缓冲分辨率约 160×160 RGB565

验证 :160×160×16 = 409,600 bit = 50KB,接近极限。

工程建议 :用BRAM做完整帧缓冲时,务必查FPGA手册计算可用BRAM总容量,再倒推最大分辨率。

4.4 代码结构(伪代码)

verilog

复制代码
// 帧缓冲BRAM(双端口)
xpm_memory_spram #(
    .ADDR_WIDTH_A(16),  // 160*160=25600,2^15=32768足够
    .DATA_WIDTH_A(16),
    .MEMORY_SIZE(160*160*16)
) u_framebuffer (...);

// SPI Flash 读取控制器
// 上电后状态机:发送读命令 → 等待数据 → 写入BRAM地址0~25599

// 显示控制器(同篇8,但数据源从BRAM读取)
always @(posedge pclk) begin
    if (de) begin
        rd_addr <= row * 160 + col;
        rgb <= framebuffer_dout; // 从BRAM读出的像素
    end
end

五、什么时候该放弃无DDR方案?

当你的需求满足以下任意两条时,请考虑回到DDR方案:

  1. 分辨率 ≥ 800×480,且需要全彩色(RGB888)
  2. 需要显示 复杂图片 (照片、地图、视频帧)
  3. 数据源是 异步的 (如网络、SD卡、随机到来的图像)
  4. 需要多图层叠加透明混合
  5. 需要缩放、旋转等图像处理

此时,DDR带来的设计复杂度是值得的,因为无DDR方案会在性能、功能、开发时间上付出更高代价。


六、☕ 工程师私房话

面试题:如果摄像头输出速率低于屏幕刷新率,无DDR情况下如何尽量流畅显示?

答案 :可以使用帧重复帧保持策略。即屏幕控制器在读完一帧后,重复读取上一帧数据(如果FIFO或行缓存中保留),直到新帧到达。这会导致运动不连贯,但避免了撕裂。实现上需要至少一个完整帧的存储(又回到帧缓冲),或者使用更聪明的预测算法(不推荐)。

实际案例:用廉价FPGA驱动480×272屏显示波形

很多入门示波器、信号发生器只用内部BRAM做波形显示,因为波形区域只占屏幕一部分(如400×200),其余区域为静态刻度。这样帧缓冲可以只缓存波形区域,其他区域实时生成。部分帧缓冲是节省BRAM的实用技巧。

冷知识:为什么早期的VGA显卡没有DDR也能显示?

早期VGA显卡(如ISA总线的)使用 双端口VRAM ,本质上就是片上帧缓冲。那时分辨率低(640×480 256色),帧缓冲约300KB,集成在显卡上。现代FPGA的BRAM容量远大于早期VRAM,所以低分辨率显示完全可以脱离DDR。

相关推荐
XINVRY-FPGA2 小时前
XC7Z035-2FFG900I Xilinx/AMD Zynq-7000 SoC FPGA
人工智能·嵌入式硬件·计算机视觉·fpga开发·硬件工程·dsp开发·fpga
zlinear数据采集卡17 小时前
基准电压电路深度解析:从理论参数到ZLinear采集卡的精准参考实战
c语言·单片机·嵌入式硬件·fpga开发·自动化
ALINX技术博客1 天前
【黑金云课堂】FPGA技术教程Vitis开发:PS端SD读写
fpga开发·vitis·sd读写
尤老师FPGA1 天前
LVDS系列50:Xilinx Ultrascale系 ADC LVDS接口参考方法(十二)
fpga开发
zlinear数据采集卡1 天前
模拟输入限流保护电路深度解析:从理论原理到ZLinear采集卡的实战设计
c语言·单片机·嵌入式硬件·fpga开发·自动化
Dillon Dong2 天前
【风电控制】FPGA采集Vdc的ADC增益系数解析——从数字码到实际电压的桥梁
算法·fpga开发·变流器·风电控制
ALINX技术博客2 天前
【黑金云课堂】FPGA技术教程FPGA基础:FIFO与Uart通信
fpga开发·uart·fpga·fifo
zlinear数据采集卡2 天前
定时器电路深度解析:从经典555到STM32定时器,从ZLinear采集卡的工程化设计实战
stm32·单片机·嵌入式硬件·fpga开发·自动化
逻辑诗篇2 天前
FT-M6678+JFM7VX690T互联调试
fpga开发