您需要一块带视频输出的 FPGA 板。 我们将在 640x480 下工作,几乎任何视频输出都可以在此像素工作。 它有助于轻松地对 FPGA 板进行编程并相当熟悉 Verilog。 如果您没有开发板,请不要担心,您可以使用 Verilator 模拟器。

材料

Lattice iCE40即用型开发平台(Xilinx Artix-7)视频板(Xilinx Artix-7)使用 SDL(简单直接媒体层) 进行 Verilator 模拟

屏幕是一个微型宇宙,有自己的空间和时间。从远处看,屏幕显示出平滑的二维图像。 近距离观察,它会分解成许多单独的色块:红色、绿色和蓝色。 我们将这种复杂性隐藏在像素的抽象概念后面:我们可以控制的屏幕的最小部分。 典型的高清屏幕为 1920 x 1080:总共 200 万像素。 即使 640x480 的显示屏也有超过 300,000 个像素。屏幕每秒刷新多次,从而产生运动的错觉。 在 60 Hz 频率下,1920x1080 屏幕每秒绘制 1.24 亿像素! 快速处理大量数据的需求是在硬件级别处理图形的一大挑战。

显示连接器和布线各不相同,但 VGA、HDMI 和 DisplayPort 具有相似的数据设计。 颜色有三个通道,通常是红色、绿色和蓝色,以及水平和垂直同步信号。 可能还有音频和配置数据,但现在这并不重要。红、绿、蓝通道依次承载每个像素的颜色。当屏幕接收到水平同步和垂直同步上的新帧时,屏幕开始新的一行。同步信号是消隐间隔的一部分。

消隐间隔允许阴极射线管 (CRT) 中的电子枪移动到下一行(水平回扫)或屏幕顶部(垂直回扫)。 现代数字显示器保留了消隐间隔,并将其重新用于传输音频和其他数据。

驱动显示器

选择显示时序后,我们就可以创建视频信号了。有四个阶段:

像素时钟显示信号绘制图形视频输出(VGA、HDMI、DisplayPort)

像素时钟

我们知道我们需要 25.2 MHz 的频率,但是如何实现它呢?

FPGA 包括锁相环 (PLL),用于生成自定义时钟频率。遗憾的是,并没有配置 PLL 的标准方法。我们需要特定于供应商的设计。

我已经为我们的板子提供了实施方案:

iCE40板子:

module clock_480p (

input wire logic clk_12m, // input clock (12 MHz)

input wire logic rst, // reset

output logic clk_pix, // pixel clock

output logic clk_pix_locked // pixel clock locked?

);

localparam FEEDBACK_PATH="SIMPLE";

localparam DIVR=4'b0000;

localparam DIVF=7'b1000010;

localparam DIVQ=3'b101;

localparam FILTER_RANGE=3'b001;

logic locked;

SB_PLL40_PAD #(

.FEEDBACK_PATH(FEEDBACK_PATH),

.DIVR(DIVR),

.DIVF(DIVF),

.DIVQ(DIVQ),

.FILTER_RANGE(FILTER_RANGE)

) SB_PLL40_PAD_inst (

.PACKAGEPIN(clk_12m),

.PLLOUTGLOBAL(clk_pix), // use global clock network

.RESETB(rst),

.BYPASS(1'b0),

.LOCK(locked)

);

endmodule

开发平台:

module clock_480p (

input wire logic clk_12m, // input clock (12 MHz)

input wire logic rst, // reset

output logic clk_pix, // pixel clock

output logic clk_pix_locked // pixel clock locked?

);

localparam FEEDBACK_PATH="SIMPLE";

localparam DIVR=4'b0000;

localparam DIVF=7'b1000010;

localparam DIVQ=3'b101;

localparam FILTER_RANGE=3'b001;

logic locked;

SB_PLL40_PAD #(

.FEEDBACK_PATH(FEEDBACK_PATH),

.DIVR(DIVR),

.DIVF(DIVF),

.DIVQ(DIVQ),

.FILTER_RANGE(FILTER_RANGE)

) SB_PLL40_PAD_inst (

.PACKAGEPIN(clk_12m),

.PLLOUTGLOBAL(clk_pix), // use global clock network

.RESETB(rst),

.BYPASS(1'b0),

.LOCK(locked)

);

endmodule

显示信号

我们可以从像素时钟和显示时序生成同步信号。我们还想报告当前的屏幕位置以了解何时绘制内容。

我们用一个简单的显示模块来完成这两件事:

module sim_480p (

input wire logic clk_pix,

input wire logic rst_pix,

output logic [9:0] sx,

output logic [9:0] sy,

output logic hsync,

output logic vsync,

output logic de

);

parameter HA_END = 639;

parameter HS_STA = HA_END + 16;

parameter HS_END = HS_STA + 96;

parameter LINE = 799;

parameter VA_END = 479;

parameter VS_STA = VA_END + 10;

parameter VS_END = VS_STA + 2;

parameter SCREEN = 524;

always_comb begin

hsync = ~(sx >= HS_STA && sx < HS_END);

vsync = ~(sy >= VS_STA && sy < VS_END);

de = (sx <= HA_END && sy <= VA_END);

end

always_ff @(posedge clk_pix) begin

if (sx == LINE) begin // last pixel on line?

sx <= 0;

sy <= (sy == SCREEN) ? 0 : sy + 1; // last line on screen?

end else begin

sx <= sx + 1;

end

if (rst_pix) begin

sx <= 0;

sy <= 0;

end

end

endmodule

测试台

绘制图形

视频输出

Verilator仿真

关联项目

驱动 32×32 RGB LED 矩阵FPGA游戏台VGA时钟光束射线追踪器赛车FPGA 媒体播放器

参阅一:亚图跨际

参阅二:亚图跨际

推荐文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。