三基色是指通过其他颜色的混合无法得到的“基本色”。由于人的肉眼有感知RGB(红绿蓝)三种不同颜色的锥体细胞,因此色彩空间通常可以由RGB三种基本色来表达。
! T0 I% E0 i; ^* o5 K
自然界中的绝大部分彩色,都可以由三种基色按一定比例混合得到。
: [3 x& @" l" z ?$ X& k
所以VGA接口中,表示颜色分量的只有红绿蓝三种基色。由于VGA接口的三基色为模拟信号值,FPGA无法输出,所以在FPGA的IO到VGA接口中间要有对应的数字量转模拟量的电路。
) d8 ^4 N# L- P, B5 A4 M4 m
SANXIN – B01中采用电阻网络来实现数字量转模拟量的功能。
) ?) u1 h; K' b0 @ \" n( b6 U$ S5 S
/ q. v0 |3 i3 ^ [
1 V- H, t1 q$ _! `; k
8 |& @! f2 z. s i$ |# t
! p1 G& l( k% a2 T& {/ O) S- R
$ v+ P# P- H M: o1 ^7 G+ e& O+ y1 d
图片在数字设备中,都是由像素点构成。
, e9 ^5 a% h* G
像素是指由图像的小方格组成的,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。可以将像素视为整个图像中不可分割的单位或者是元素。不可分割的意思是它不能够再切割成更小单位,它是以一个单一颜色的小格存在。每一个点阵图像包含了一定量的像素,这些像素决定图像在屏幕上所呈现的大小。
# G$ p' ^+ G( u ~
VGA显示器上每一个像素点可以很多种颜色,由R、G、B三种颜色构成。如果每个像素点采用3位二进制数表示,即R用1bit表示,G用1bit表示,B用1bit表示,则此像素点一共可以显示8种颜色;如果每个像素点采用8位二进制数表示,即R用3bit表示,G用3bit表示,B用2bit表示,则此像素点一共可以显示256种颜色。在SANXIN – B01开发板中,采用RGB332的进行表示。
- j2 W7 C2 f+ U) @8 n
在VGA显示器中,像素点RGB的二进制数越多,能够表示的颜色就越多,此时,显示的图像就会越清晰。
2 B0 m4 g8 L; r6 T# O# Z( _* Z
在VGA显示器中,像素点的个数也是一个非常重要的一个指标。
, S+ h0 ]+ R) o
我们可以打开自己电脑的显示分辨率。
+ w0 X- a. k, j1 o( Y; M
( n9 r. E1 D1 [% p# Z
% I$ x$ J' ~5 \# Q+ @
7 Q/ o" m% A7 I& x; {: A
% d( c$ I: u) R4 o
0 S N- d/ L# N _. u O/ i! `& m" h
分频率有各种模式,但是基本都是固定好的。分辨率都是长乘宽,前面的数为长,后面的数为宽。长表示屏幕横向可以有多少个像素点;宽表示屏幕纵向可以用多少个像素点。一般来说屏幕都是扁平的,所以长一般都会比宽大。
6 U" Q) u7 Q" l0 d
像素的多少不改变实际物理的尺寸大小,只是呈现的清晰度不同。可以对比500万像素的相机拍的图片和2000万像素的相机拍的图片,大小相同的情况下,清晰度是不同的。
; u2 N/ I$ B% u: p
只要我们按照显示器能够支持的分辨率的长和宽,将对应的像素点传输给VGA接口就可以了。但是VGA协议中,要求进行传输像素点的同时,还需要去传输一部分的同步信号。
2 B% z8 \) a5 d o! X4 u
显示器扫描方式分为逐行扫描和隔行扫描:逐行扫描是扫描从屏幕左上角一点开始,从左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,每行结束时,用行同步信号进行同步;当扫描完所有的行,形成一帧,用场同步信号进行场同步,并使扫描回到屏幕左上方,开始下一帧。隔行扫描是指电子束扫描时每隔一行扫一线,完成一屏后在返回来扫描剩下的线,隔行扫描的显示器闪烁的厉害,会让使用者的眼睛疲劳。在此我们选择逐行扫描的方式。
3 B/ c! F" e2 k/ T9 O! ]1 O' q
. a% x+ W5 ^7 a3 C
( K- Y1 j# \3 I$ F' I9 x' J+ ~
: F S: o( p' W/ h: H2 {3 F
8 Y9 J; F& z# c1 e1 n! J
# V8 @0 I; | t, z$ C
VGA的时序主要包括行时序与场时序两个部分。其中行时序主要包括:行同步(Hor Sync) 、行消隐(Hor Back Porch) 、行视频有效(Hor Active Video)和行前肩(Hor Front Porch)这四个参数,行时序的时序图如下图所示:
$ b+ e6 K5 _2 F/ W# Q; Q5 L
; ?) U5 y. V( |0 g
: |. h0 s" A: V k3 N1 [" R/ J/ H* e" |: e3 ]: \2 A' u) w
8 C5 K: F: A3 s7 X& \6 @- Q+ ^
场时序主要包括:场同步(Ver Sync) 、场消隐(Ver Back Porch) 、场视频有效(Ver Active Video)和场前肩(Ver Front Porch)这四个参数,场时序的时序图如下图所示:
2 G+ ~$ r( @: P2 c
& Y9 @: T+ R# j
; A9 V" X+ i# l8 g& X$ L3 X/ k3 w# M- `
. I+ V7 w5 v- y8 v. h
需要注意的有三点:
1、行时序是以”像素”为单位的, 场时序是以”行”为单位的。
2、VGA 工业标准显示模式要求:行同步,场同步都为负极性,即同步脉冲要求是负脉冲。
3、VGA 行时序对行同步时间、 消隐时间、 行视频有效时间和行前肩时间有特定的规范, 场时序也是如此。常用VGA 分辨率时序参数如下表所示:
: [1 G4 S5 r$ R! ?% d. f( V5 ^
0 b4 ^4 ]; \% j% W! [: c$ o
( ^, y0 n$ W$ N- u5 C8 k& @0 j: u, A: x0 @' Q
% q Y1 |3 C" L b2 ]# d* r
本实验中选择640x480@60Hz。时钟的速率为25.175MHz,我们在设计时,时钟速率选择为25MHz 即可。
5 K8 f4 \* r! G" _4 D
- 设计要求
& @1 B" [+ a, _! ~- F# K
控制VGA显示器显示全屏红色或者其他颜色。
' o5 K, ~2 }* [- s' v7 o7 n
当我们选择640x480@60Hz的标准后,根据对应格式可以发现,此标准的一行为800个像素值,共有525行。也就是说并不是所有的像素值都可以显示出来,显示出来的只有中间的640列和480行,其他的像素值不显示(要求其他的像素值为黑色,即RGB全部给0)。
5 E" p5 h* M% m( W7 L
选择标准需要25MHz的时钟,我们可以选择使用锁相环来进行生成25MHz的时钟。
( e! }6 i' P4 ^5 N8 I% q& ~1 K
扫描方式为逐行扫描,从左上角开始。定义一个列坐标计数器(cnt_hs),每个驱动时钟周期加1,当一行结束后,计数器也同时清零。一行为800个像素值,所以计数器将会在0到799无限循环。HSYNC信号在此计数器的前96的计数值拉低,其他时间拉高即可。
7 K O3 [* {9 }; M4 U: O8 N+ j
定义一个行坐标计数器(cnt_vs),扫描完一行后,进行加一,当一帧图片结束后,计数器清零。一行为800个像素值,所以等cnt_hs为799时,cnt_vs进行加一或者清零,由于一帧图片共有525行,所以计数器在0到524之间无限循环。VSYNC信号在此计数器的前两个计数器拉低,其他时间拉高即可。
, a7 T/ z/ C' u; c1 h" i& F, V5 X
根据cnt_hs和cnt_vs,按照对应的标准,就可以得出显示的640列和480行的具体位置。
列显示的范围为:hs_a+hs_b+hs_c>cnt_hs>hs_a+hs_b-1.
行显示的范围为:vs_f+vs_g+vs_h>cnt_vs>vs_f+vs_g-1.
. z$ k/ Q! e$ ?% A. R5 b$ S4 _
同时在两个有效显示区范围内,就可以显示出来。
* V. o; k: Q+ |$ z5 s( C* C7 O
- 设计架构和信号说明
7 t/ F% _: W# V" B* U v" ~
此设计命名为vga_drive。
& u6 i4 }9 u% [; z* u' O, W0 U
$ Q# V2 Z. V' U" i4 [( e
" ~; A% b: e, Z2 p* v" G
0 r) U! H4 c. ?3 u/ T5 B' d& @
pll_vga为锁相环,利用外部输入的50MHz的时钟,产生VGA协议所需要的25MHz的时钟。
& G8 o0 p |. Y2 f+ m+ ]: e* V) L
vga_ctrl为VGA协议的驱动模块。
. Y z* H) Z. e! \6 O
- N( u$ X9 s" W: U O
! P; D& R. d& D/ k/ \9 n* M; T$ X% \
' l1 j: P" m- m& ?, [
- vga_ctrl设计实现; I" ]6 K( J) c% i% a* v M4 g
1 L' R. v+ k7 b Z& P9 ^7 o
按照设计分析中的设计方法,进行设计即可。
1 W# C( {: ?( d. ?, t. Y* N( |
hs_en为列有效显示的表示信号;vs_en为行有效显示的表示信号。
E8 E6 u/ Q! s+ X9 R, }
设计代码为:
, L3 L* t; S8 R: `" R# [
) R: D' i) w6 x! q! J; i5 @( q! x0 ~4 N5 u& B5 Q
在设计中,给出的全屏颜色为红色。
Z' r- A0 v: y7 t( u6 z4 D2 |0 B3 {0 R
- vga_drive设计实现2 d9 V ^4 g0 o) j
0 x2 i$ w/ r+ P. X
调用锁相环,产生25MHz的时钟。
# E6 x, K$ Z; U3 w3 ~
利用锁相环的输出锁定信号当作后续模块的复位信号使用。
; E' _. }, w5 d7 l+ Y* z& g
设计代码为:
% I; I/ c+ h$ k3 m4 o$ \- k2 {9 V
8 O9 I: e k# K4 F3 E
# f* A: C, k8 e' @7 _; `9 m; z5 B! `5 {% O- ?4 k @
仿真时只需要给出clk和rst_n的信号即可,在此不做介绍。设计者可以通过modelsim观看是否每一行输出640个红色值,以及是否每一帧输出480行。仿真时间较长,大约等待20ms,就可以仿真完一帧图像。
' [" ~, c+ D4 @# Q" [7 l8 I
- 板级测试
7 X/ L+ t7 H* O& z" F0 V! y$ @
& @/ m& g/ ]% c
利用VGA线,将开发板的VGA接口和显示屏幕的VGA接口相连接,打开显示器。
# o5 x6 H% f+ |- B6 g/ B) ^2 j
分配管脚,生成配置文件后,进行下板。
2 |0 M2 e5 |3 j/ `- K( _3 L
红色全屏如下:
' n+ v+ g- E% Q: \
/ i, F. {4 }7 h: B
4 }# u% i/ J, N0 M1 m1 G% U; S0 W- I. @. C
# R" A! r a' d i9 S
' J5 ^. K% i6 T" d* ?
更改颜色为绿色,vga_rgb <= 8’b000_111_00,生成配置文件后,下板。
, M ^3 ~8 g9 V8 Z7 c+ Y
绿色全屏为:
6 u9 A( c( B* q4 f. h+ L
2 q7 z- X3 y( O( X L8 O
9 x# ^& J4 n$ \. [9 z5 k" N1 K1 e/ R0 E$ c
5 L- n' h' ?+ X, d6 X
# o- F, E* u9 _ M
根据RGB332的排列,可以自由更改。不同的基色也可以进行混搭,进行验证。