新闻  |   论坛  |   博客  |   在线研讨会
Verilog 编写的基于VGA的动画图像显示_fpga的VGA接口设计_明德扬资料
billow兔 | 2017-08-03 09:10:57    阅读:688   发布文章

 

 

 

 

 

 

 

 

 

 

Verilog 编写的基于VGA的动画图像显示

明德扬科技教育有限公司

 

 

 

 

官网:www.mdy-edu.com

淘宝:mdy-edu.taobao.com

QQ群:544453837

QQ咨询:158063679


VGA显示动画

1 功能概述

显示器的像素按照从左到右,从上到下的顺序进行刷新。从上到下刷新完一遍称为一帧,屏幕刷新频率就是说屏幕一秒钟能够刷新多少帧,当达到一定的帧数,我们的肉眼也就分辨不出来了,这样我们就看到我们的电脑屏幕,我们在操作的时候是连续的了。运用这些科学原理完成在VGA接口的显示屏上动画功能,是相关技术人员必备的技能之一。

动画的概念不同于一般意义上的动画片,它集合了绘画、漫画、电影、数字媒体、摄影、等众多艺术门类于一身的综合艺术。可以理解为使用绘画的手法,创造生命运动的艺术。较规范的定义是采用逐帧拍摄对象并连续播放而形成运动的影像技术。通过把人物的表情、动作、变化等分解后画成许多动作瞬间的画幅,再连续形成一系列画面,给视觉造成连续变化的图画。它自19世纪上半叶诞生至今,  经过了一个多世纪发展,已经有了较为完善的理论体系和产业体系,电脑科技的高速进步更是使传统动画产业突飞猛进,目前已被广泛应用到商业中。

与幻灯和图片不同的是,计算机动画基本原理与电影、电视一样,都是视觉暂留原理。即在前一幅画还没有消失前播放下一幅画,给人造成一种流畅的视觉变化效果。本案例即采用FPGA在VGA接口显示屏上,运用verilog语言在明德扬至简开发板二代实现动画显示效果。

本项目功能要求如下:

(1)该VGA接口输出的图像分辨率为下列表格中第一种640*480,即帧长为800*525。

(2)VGA显示要求:复位后,屏幕中央显示直径为10的蓝色圆点;按下按键0,圆点图像逐渐变大,直至直径变为400;再按一下按键0,圆点逐渐变小,直到直径为10。此过程要有明显的动画效果。

 

2 设计思路

VGA显示中,FPGA需要产生5个信号:R、G、B三基色信号,行同步信号HS和场同步信号VS,接口对应孔如下所示:

图1   VGA信号接口对应

像素是产生各种颜色的基本单元。根据物理学中的混色原理,三色发光的亮度比例适当,可呈现白色。适当的调整发光比例可以出现不同的颜色。三基色混色原理示意图如下图所示:

图2   三基色混色原理

 

颜色

绿

R

0

0

1

1

0

0

1

1

G

0

0

0

0

1

1

1

1

B

0

1

0

1

0

1

0

1

表1  三基色颜色编码

 

上表的RBG一共有8组合,也就是说可以产生8种颜色,但是显示器显示的色彩是非常丰富的,远多于8种颜色。那么,这是如何做到的呢?

对于显示器来说,RGB的三个信号其实是模拟信号,其电平的高低,可以表示颜色的深浅,利用这个原理,就可以产生丰富的色彩。为了控制电压的高低,我们必须用到DA芯片。例如,下图中FPGA产生RGB三种信号,这时RGB都是多位的数字信号。DA芯片根据数字信号的值,产生不同电压的模拟信号rgb。

图3   DA芯片工作原理

模块划分和信号列表如下:

模块划分

 

顶层模块信号列表

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

系统复位信号,低电平有效。

key_en

I

1

按键信号

lcd_hs

O

1

行同步信号。

lcd_vs

O

1

场/帧同步信号。

lcd_rgb

O

16

RBG三基色信号。

 

 

PLL分频模块信号列表

信号名

I/O

位宽

说明

inclk0

I

1

输入工作时钟50MHz。

c0

O

1

输出时钟25MHz。

 

 

VGA接口计数模块信号列表

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟25MHz。

rst_n

I

1

系统复位信号,低电平有效。

key_en

I

1

按键信号,按下高电平。

hys

O

1

行同步信号。

vys

O

1

场/帧同步信号。

lcd_rgb

O

16

RBG三基色信号。

 

3 程序设计

顶层模块代码

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

module   vga_exec1(

clk      ,

rst_n    ,

lcd_hs   ,

lcd_vs   ,

lcd_rgb  ,

key_en

    );

 

    parameter               PICTURE_W = 16;

 

    input                   clk           ;

input                   rst_n         ;

input                   key_en       ;

    output                  lcd_hs        ;

    output                  lcd_vs          ;

    output    [PICTURE_W:0]   lcd_rgb       ;

 

    wire                    clk_0         ;

 

    parameter               ROW_W  =    10;

 

    wire                                lcd_hs        ;

    wire                    lcd_vs          ;

    wire [PICTURE_W-1:0]      lcd_rgb       ;

 

vga_pll   module_1(

                    .inclk0     (clk      ),

                    .c0        (clk_0  )

                    );

 

vga_driver   module_6(   

                       .clk        (clk_0  ),

                       .rst_n      (rst_n    ),

                       .hys        (lcd_hs ),

                       .vys        (lcd_vs ),

                       .lcd_rgb     (lcd_rgb),

                  .key_en     (key_en)

                    );

endmodule

 

 

VGA计数模块代码

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

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

module   vga_driver(

                                               clk        ,

                                               rst_n      ,

key_en    ,

                                               hys       ,

                                               vys       ,

                                         lcd_rgb

               );

 

    parameter     PICTURE_W  =  16  ;

    parameter     ROW_W       =  10  ;

 

    parameter     X0_INIT      =  273 ;

    parameter     X1_INIT      =  373 ;

    parameter     Y0_INIT      =  202 ;

    parameter     Y1_INIT      =  282 ;

    parameter     X_GAP       =  5  ;

    parameter     Y_GAP       =  4  ;

    parameter     CNT_TIME    =  625 ;

 

    parameter     TIME_1S     =  25000000       ;

    parameter     TIME_20MS  =    500000       ;

    parameter     X_CENT      =    323          ;

    parameter     Y_CENT      =  242            ;

    parameter     X_PRE_CENT  =  X_CENT + 141    ;

    parameter     Y_PRE_CENT  =  Y_CENT +    32  ;

 

    parameter     WHITE       =  16'b11111_111111_11111  ;

    parameter     RED         =  16'b11111_000000_00000  ;

    parameter     GREEN       =    16'b00000_111111_00000  ;

    parameter     BLUE        =  16'b00000_000000_11111  ;

    parameter     YELLOW     =  16'b11111_111111_00000  ;

    parameter     PURPLE     =  16'b01111_000000_10000  ;

    parameter     CYAN       =  16'b01111_111111_11111  ;

    parameter     PINK        =  16'b11111_011111_01111  ;

    parameter     BLACK       =  16'b00000_000000_00000  ;

 

    input                  clk      ;

    input                  rst_n    ;

    input                  key_en   ;

 

    output                 hys      ;

    output                 vys      ;

 

 

    output [PICTURE_W-1:0]   lcd_rgb    ;

reg   [PICTURE_W-1:0]   lcd_rgb    ;

 

reg    [ROW_W-1:0]     h_cnt      ;

reg    [ROW_W-1:0]     v_cnt      ;

reg                    hys      ;

reg                    vys      ;

reg                    valid_area ;

reg                                           key_flag  ;

reg[19:0]                    shake_cnt ;

reg                                      flag      ;

 

reg[ 9:0]               cnt_time     ;  

reg                   change_flag ;

reg[19:0]              range      ;

reg[19:0]              distance    ;

reg                   direction   ;

 

    always @(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

h_cnt<= 0;

        end

        else if(add_h_cnt)begin

            if(end_h_cnt)

h_cnt<= 0;

            else

h_cnt<= h_cnt   + 1;

        end

    end

    assign add_h_cnt = 1;      

    assign end_h_cnt =   add_h_cnt&&h_cnt== 800-1;  

 

    always @(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

v_cnt<= 0;

        end

        else if(add_v_cnt)begin

            if(end_v_cnt)

v_cnt<= 0;

            else

v_cnt<= v_cnt   + 1;

        end

    end

    assign add_v_cnt = end_h_cnt;      

    assign end_v_cnt =   add_v_cnt&&v_cnt== 525-1;  

 

    always@(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

hys<= 0;

        end

        else if(add_h_cnt&&h_cnt==96   - 1)begin

hys<= 1;

        end

        else if(end_h_cnt)begin

hys<= 0;

        end

    end

        

    always@(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

vys<= 0;

        end

        else if(add_v_cnt&&v_cnt== 2   - 1)begin

vys<= 1;

        end

        else if(end_v_cnt)begin

vys<= 0;

        end

    end

 

    always    @(*)begin

valid_area =   h_cnt>=141 &&h_cnt<=786 &&v_cnt>=32   &&v_cnt<=515;

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

shake_cnt<=   0;

        end

        else if(add_shake_cnt)begin

            if(end_shake_cnt)

shake_cnt<=   0;

            else

shake_cnt<=   shake_cnt + 1;

        end

        else  begin

shake_cnt<=   0;

        end

    end

    assign    add_shake_cnt = key_en&& flag==0;

    assign    end_shake_cnt = add_shake_cnt&&shake_cnt==TIME_20MS-1;

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            flag <= 0;

        end

        else if(end_shake_cnt)begin

            flag <= 1;

        end

        else if(key_en==0)begin

            flag <= 0;

        end

    end

 

    always @(posedgeclk or negedgerst_n)begin

        if(!rst_n)begin

cnt_time<= 0;

        end

        else if(add_cnt_time)begin

            if(end_cnt_time)

cnt_time<= 0;

            else

cnt_time<=   cnt_time + 1;

        end

    end

    assign add_cnt_time =   key_flag&&add_h_cnt&&h_cnt==0 &&v_cnt==0;      

    assign end_cnt_time =   add_cnt_time&&cnt_time== CNT_TIME -1;  

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

key_flag<= 0;

        end

        else if(end_shake_cnt)begin

key_flag<= 1;

        end

        else if(end_cnt_time)

key_flag<= 0;

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            direction <= 1'b0;

        end

        else if(cnt_time==0   &&end_shake_cnt) begin

            direction <= ~direction;

        end

    end

 

    always    @(*)begin

        if(h_cnt==0 &&v_cnt==0   &&cnt_time!=0) begin

change_flag  = 1'b1;

        end

        else begin

change_flag  = 1'b0;

        end

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

            range <= 25 ;

        end

        else if(h_cnt==0 &&v_cnt==0   &&change_flag) begin

            if(direction)

                range <= range + 64;

            else

                range <= range - 64;

        end

    end

 

    always    @(*)begin

        distance   = ((h_cnt - X_PRE_CENT) * (h_cnt -   X_PRE_CENT)) +

((v_cnt -   Y_PRE_CENT) * (v_cnt - Y_PRE_CENT));

    end

 

    always    @(posedgeclk or negedgerst_n)begin

        if(rst_n==1'b0)begin

lcd_rgb<=   8'h0;

        end

        else if(valid_area)begin

            if(distance < range)begin

lcd_rgb<=   BLUE;

            end

            else  begin

lcd_rgb<=   WHITE;

            end

        end

        else begin

lcd_rgb<= 0;

        end

    end

endmodule

 

 


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客