【发布时间】:2015-12-30 04:52:41
【问题描述】:
我是 FPGA 初学者,无法理解如何控制 VGA 信号与VGA交互,以及如何正确生成VGA控件 信号(使用 Verilog)以获得更复杂的规范:
看起来,水平和垂直同步信号中的低频部分 对应于从一行过渡到下一行,以及过渡 分别从右下角到左上角。但 VGA是由那些低信号“控制”的吗?做那些低信号 “告诉” VGA 切换到下一行还是跳回起点?
后廊和前廊是否满足设置时间和 保持时间?门廊的持续时间是否仅在 VGA 时序表中给出 所需的最小值(即我可以将门廊设置为比 时间表中的给定值?)
这是最让我困惑的:从两个连续的 水平和垂直同步信号,VGA到底是怎么知道的 (或者我知道)它在屏幕上显示的究竟是哪个point?如果计时 是唯一的因素,这是否意味着我必须非常注意 完美匹配 RPG 控制信号和水平同步和垂直同步信号?如果 答案是肯定的,那么我有更多的问题,我只能 以我的作业为例进行描述:
在这个作业中,我们使用 FPGA(Spartan 入门板)的内置 50MHz 时钟,VGA 的像素被指定为 800x600。帧速率指定为 72Hz。
VGA时序表给出了以下同步信号结构:
水平同步: | 0---后廊(104)---103 | 104---显示(800)---903 | 904---前廊(16)---919 | 920__脉冲宽度(120)__1039 |
垂直同步: | 0---后廊(23)---22 | 23---显示(600)---622 | 623---前廊(37)---659 | 660__脉宽(6)__665 |
这似乎意味着对于屏幕上一行中的每个像素,我花费 1 时钟周期(20ns)就可以了。但是,对于许多复杂的情况,我会 想要根据像素在屏幕上的位置来控制像素的颜色 也许还有很多附加条件,例如 当前位置与另一个位置,某些状态等。现在,如果像素的位置取决于水平和垂直像素计数器,并且颜色进一步取决于位置,我该如何及时匹配它们?另外,如果我的逻辑必须花费超过 20ns 来决定像素的颜色怎么办?这会使 VGA 屏幕上的图像完全崩溃吗?
实际上我已经完成了我的任务,但是我发现我的代码很乱 我完全不知道它为什么会起作用:
例如,部分作业要求我们展示一颗星 每 0.5 秒改变一次颜色。我的实现如下:
//----------------pixel counters----------------
always@(posedge CLK or posedge RESET) begin
if(RESET) h_count <= 11'd 0;
else if (h_count >= 11'd 1039) h_count <= 11'd 0;
else h_count <= h_count + 11'd 1;
end
always@(posedge CLK or posedge RESET) begin
if(RESET) v_count <= 10'd 0;
else if (v_count >= 10'd 665) v_count <= 10'd 0;
else if (h_count == 11'd 1039) v_count <= v_count + 10'd 1;
else v_count <= v_count;
end
//----------------h- and v- sync----------------
always@(posedge CLK or posedge RESET) begin
if(RESET) VGA_HSYNC <= 1'b 0;
else VGA_HSYNC <= (h_count >= 11'd 0) & (h_count <= 11'd 919);
end
always@(posedge CLK or posedge RESET) begin
if(RESET) VGA_VSYNC <= 1'b 0;
else VGA_VSYNC <= (v_count >= 10'd 0) & (v_count <= 10'd 659);
end
//----------------a frame counter and a flag----------------
always@(posedge CLK or posedge RESET) begin
if(RESET) frame_count <= 6'd 0;
else if (frame_count >= 6'd 49) frame_count <= 6'd 0;
else if(v_count == 10'd 665) frame_count <= frame_count + 6'd 1;
else frame_count <= frame_count;
end
always@(posedge CLK or posedge RESET) begin
if(RESET) color_flag <= 1'd 0;
else if (frame_count == 6'd 49) color_flag <= ~(color_flag);
else color_flag <= color_flag;
end
//----------------RGB control----------------
always@(posedge CLK or posedge RESET) begin
if(RESET) VGA_RGB <= 3'b 000;
else if(display) begin //display is high when counters in valid range
casez({tree, star, snow}) //these are outputs from submodules that decides the "shapes" of objects on screen
3'b ??1: VGA_RGB <= 3'b 111; //white snow
3'b ?10: VGA_RGB <= (color_flag) ? (3'b 110) : (3'b 111);
//switching between yellow and white
3'b 100: VGA_RGB <= 3'b 010; //green tree
default: VGA_RGB <= 3'b 001; //blue background
endcase
end
else VGA_RGB <= 3'b 000; //for transitions
end
在我看来,我的 h_count 和 v_count 直接决定了我的 VGA_HSYNC 和 VGA_VSYNC。但是我的 VGA_RGB 至少取决于 color_flag,它进一步取决于 frame_count,它取决于 h_count 和 v_count。这不应该导致几个时钟周期的延迟吗?该代码是可合成的,并且确实产生了我想要显示的内容。但是我的 VGA_RGB 究竟是如何与 VGA_HSYNC 和 VGA_VSYNC 及时同步的???我是不是在想这个问题?还是我只是幸运?我错过了什么?
【问题讨论】:
-
要部分回答您的问题,通常您希望有一些内存块(芯片上或芯片外)来存储您的像素数据。这样,您可以独立于 VGA 控制器对其进行操作(进行更改、更新等),并且可以根据您的需要/需要进行任何更改。
标签: verilog fpga system-verilog