在FPGA开发中,图像显示是检验设计基本功的经典项目。屏幕上每个像素的亮灭,背后是像素时钟、水平与垂直同步信号在纳秒级精度下协作。很多人一上来就堆代码,却跳过了时序参数的计算,结果画面花屏、撕裂、偏色。这篇文章把"画面怎么刷到屏幕上"这条链路讲透。
VGA显示的本质是逐行扫描。FPGA需要一个像素时钟(pixel clock),每个上升沿输出一个像素。以VGA 640×480为例,像素时钟25 MHz,即每40 ns吐出一个像素。但一行的总周期不是640个像素,而是640(有效区)+48(消隐区)=688个像素周期。一帧同理,不是480行,而是482行。
FPGA里用三级计数器实现:
像素计数(0~639):有效区输出RGB数据,消隐区输出黑
行计数(0~479):控制HSYNC在消隐区拉低
帧计数:控制VSYNC在消隐区拉低
HSYNC和VSYNC告诉显示器"换行"或"换帧",DE(Data Enable)信号标记当前像素是否有效。三个信号配合像素时钟,显示器才能稳定刷帧。
640×480@RGB888的图像数据量为640×480×3≈0.9 MB。中低端FPGA的片内BRAM通常只有几百KB,装不下。实际项目中的分界:
小图(如160×120、RGB565):片内BRAM或ROM直接存
大图(640×480及以上):外挂DDR SDRAM,通过MIG/DDR IP读写
帧缓冲的核心逻辑是双指针:写指针由上位机(串口、以太网)驱动,把图像数据灌进存储器;读指针由像素时钟驱动,在有效区按行、按像素顺序读出RGB送到屏幕。两个指针必须用双缓冲机制隔离——写端只写"非显示帧",读端只读"正在显示的帧",VSYNC下降沿做帧切换,否则画面撕裂。
上位机传图 → 串口/以太网解包 → 写入DDR/BRAM → 像素时钟驱动读指针 → 输出RGB+HSYNC+VSYNC+DE → VGA/DVI接口 → 显示器
640×480@RGB888需要约0.9 MB,多数中低端器件的片内BRAM只有100~500 KB,放不下。如果做QVGA(320×240)且用RGB565(2字节/像素),数据量约150 KB,片内BRAM可以容纳。但实际工程建议直接上DDR,留出余量,也方便后续扩展到1080p分辨率。
绝大多数原因是写指针和读指针没有做帧同步。在VSYNC下降沿把"正在显示的帧"和"待写帧"做一次双缓冲切换,写端只操作非显示帧。如果做了双缓冲仍撕裂,检查读指针是否在消隐区被意外复位或打断,导致读地址跳行。
画面能不能稳定显示,关键不在代码量,在于时序参数算对、帧缓冲读写隔离做对。你手头那块显示器的分辨率是多少,对应的像素时钟和消隐区参数该怎么倒推?想清楚这个,再看代码就不迷路了。
宸极教育FPGA课程覆盖从VGA时序计算、DDR帧缓冲设计到以太网图像传输的完整链路,21个实战项目中包含图像显示与高速数据通路设计。点击页面右下角客服窗口,告诉我们你的学习起点和目标方向,我们帮你规划一条最短路径。
未经许可,禁止转载!
下一篇:没有了