Menu Close

FPGA图像处理之二:VGA彩条显示Verilog实现

上一篇介绍了vga显示图像的基础知识。这一节我们来实现vga彩条显示。实现步骤:

1、接口分析。module的接口,除了一般的clk,rst,还需要输出水平同步信号,垂直同步信号,以及RGB颜色值。

2、扫描过程各个参数的值。这个可以通过查阅VISA手册(见附件),得到想要输出分辨率下的各个参数值。主要有时钟频率、同步信号极性、同步信号宽度、后沿宽度、边框、显示区域、前沿等。

3、调用PLL。VGA时钟频率一般和输入钟频率不同,为了得到比较精确的VGA始终频率,需要使用PLL输出。

4、水平和垂直扫描计数。通过设置水平和垂直两个计数器来确定当前扫描位置,也可以看作当前扫描像素的坐标。

5、同步信号输出。根据当前扫描点位置和第二步中参数值来决定水平、垂直同步信号的输出。

6、判断是否在显示区域。根据当前扫描点的位置和各个参数值,判断行是否在显示区域,列是否在显示区域,如果行、列都在显示区域,则当前扫描点在显示区域。

7、输出RGB值。当扫描点进入显示区域后,输出RGB的值。否则,RGB应当输出零。

程序参考代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
module VGA_colorbar(
input       wire                sysclk,         //系统时钟,也就是板子的时钟
input       wire                rst,

output      reg     [3:0]       R,              //输出的颜色值
output      reg     [3:0]       G,              //输出的颜色值
output      reg     [3:0]       B,              //输出的颜色值
output      wire                HS,             //水平同步信号
output      wire                VS              //垂直同步信号

);

//显示分辨率 640*480@60Hz
//时钟25.175M
localparam      HPOLA           =       0;  //水平同步信号极性
localparam      VPOLA           =       0;  //垂直同步信号极性

localparam      HTOTAL          =       800;//水平总像素数
localparam      HSYNCP          =       96; //水平同步信号像素数
localparam      HBACKP          =       40; //扫描后沿像素数
localparam      LBorder         =       8;  //左边框
localparam      HDISP           =       640;//显示区域
localparam      RBorder         =       8;  //右边框
localparam      HFRONTP         =       8;  //扫描前沿像素数


localparam      VTOTAL          =       525;//垂直总像素数
localparam      VSYNCP          =       2;  //垂直同步信号
localparam      VBACKP          =       25; //扫描后沿像素数
localparam      TBorder         =       8;  //顶边框
localparam      VDISP           =       480;//显示区域
localparam      BBorder         =       8;  //底边框
localparam      VFRONTP         =       2;  //扫描前沿像素数


wire                vgaclk;
wire                locked;
wire                vgarst;

assign  vgarst = ~locked;                   //locked为高表示时钟正常,此时不复位

//使用锁相环来输出指定时钟
pll pll_inst (
    .areset ( rst ),
    .inclk0 ( sysclk ),
    .c0 ( vgaclk ),
    .locked ( locked )
    );


   
reg         [9:0]   hcnt;                   //行计数
reg         [9:0]   vcnt;                   //场计数
   
   
//行计数
always@(posedge vgaclk or posedge vgarst) begin
if(vgarst)
    hcnt <= 0;
else
    if(hcnt == HTOTAL - 1)
        hcnt <= 0;
    else
        hcnt <= hcnt + 1;
end
   

//场计数
always@(posedge vgaclk or posedge vgarst) begin
if(vgarst)
    vcnt <= 0;
else
    if((hcnt == HTOTAL - 1) && (vcnt == VTOTAL - 1))
        vcnt <= 0;
    else if(hcnt == HTOTAL - 1)
        vcnt <= vcnt + 1;
    else
        vcnt <= vcnt;
end


//行同步信号输出
assign HS = (hcnt <= HSYNCP - 1)  ?  HPOLA : ~HPOLA;

//场同步信号输出
assign VS = (vcnt <= VSYNCP - 1)  ?  VPOLA : ~VPOLA;


//显示区域的判断
wire    h_disp;
assign h_disp = (hcnt > (HSYNCP + HBACKP + LBorder - 1) &&
                hcnt < (HSYNCP + HBACKP + LBorder + HDISP - 1)) ? 1'b1 : 1'b0;
               
wire    v_disp;
assign v_disp = (vcnt > (VSYNCP + VBACKP + TBorder - 1) &&
                vcnt < (VSYNCP + VBACKP + TBorder + VDISP- 1))  ? 1'b1 : 1'b0;


wire disp;
assign disp = h_disp && v_disp;


//如果扫描到显示区域内部,则输出颜色值
always@(posedge vgaclk or posedge vgarst) begin
if(vgarst)
    begin
        R <= 4'b0000;
        G <= 4'b0000;
        B <= 4'b0000;
    end
else
    if(disp)
        begin
            if(hcnt < (HSYNCP + HBACKP + LBorder) + HDISP/5 - 1)
                begin
                    R <= 4'b1111;
                    G <= 4'b0000;
                    B <= 4'b0000;
                end
            else if(hcnt < (HSYNCP + HBACKP + LBorder) + HDISP*2/5 - 1)
                begin
                    R <= 4'b0000;
                    G <= 4'b1111;
                    B <= 4'b0000;
                end
            else if(hcnt < (HSYNCP + HBACKP + LBorder) + HDISP*3/5 - 1)
                begin
                    R <= 4'b0000;
                    G <= 4'b0000;
                    B <= 4'b1111;
                end
            else if(hcnt < (HSYNCP + HBACKP + LBorder) + HDISP*4/5 - 1)
                begin
                    R <= 4'b1111;
                    G <= 4'b1111;
                    B <= 4'b0000;
                end
            else if(hcnt < (HSYNCP + HBACKP + LBorder) + HDISP - 1)
                begin
                    R <= 4'b1111;
                    G <= 4'b1111;
                    B <= 4'b1111;
                end
        end    
    else
        begin
            R <= 4'b0000;
            G <= 4'b0000;
            B <= 4'b0000;
        end
end

endmodule

附件下载

Posted in FPGA, IC, 教材与教案
0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论

相关链接