当前位置:文档之家 > 电子设计自动化课程设计报告

电子设计自动化课程设计报告

电子设计自动化

课程设计报告

学生姓名:

学号:

课设题目:VGA彩条信号显示控制器设计同组人:

电子设计自动化课程设计报告

郝欣欣

一、课程设计内容

1、使用Verilog语言和Modelsim仿真器完成可显示横彩条、竖彩条、棋盘格相间的VGA

控制器的设计和验证

2、设计并验证可显示英语单词”HIT”的VGA控制器

3、使用Quartus II和SOPC实验箱验证设计的正确性

4、Verilog代码要符合微电子中心编码标准

二、FPGA原理

CPLD、FPGA是在PAL、GAL等基础上发展起来的一种具有丰富的可编程I/O引脚、逻辑宏单元、门电路以及RAM空间的可编程逻辑器件,几乎所有应用门阵列、PLD和中小规模通用数字集成电路的场合均可应用FPGA和CPLD器件。CPLD的设计是基于乘积项选择矩阵来实现的,而FPGA基于查找表来设计的。查找表就是实现将输入信号的各种组合功能以一定的次序写入RAM中,然后在输入信号的作用下,输出特定的函数运算结果。其结构图如图1所示:

电子设计自动化课程设计报告

图1. FPGA查找表单元

一个N输入查找表(LUT,Look Up Table)可以实现N个输入变量的任何逻辑功能,如N输入“与”、N输入“异或”等。

输入多于N个的函数、方程必须分开用几个查找表(LUT)实现(如图2

所示)。

电子设计自动化课程设计报告

图2 FPGA查找表单元内部结构

该系统设计中,FPGA芯片用的是ALTERA公司的EP1K30QC208-2,它的系统结构如图3所示。它由若干个逻辑单元和中央布线池加I/O端口构成

电子设计自动化课程设计报告

图3 EP1K30QC208内部结构

三、VGA接口

VGA的全称为Video Graphic Array,即显示绘图阵列。在PC行业发展的初期,VGA以其支持在640X480的较高分辨率下同时显示16种色彩或256种灰度,

同时在320X240分辨率下可以同时显示256种颜色的良好特性得到广泛支持。后来,厂商们纷纷在VGA基础上加以扩充,如将显存提高至1M并使其支持更高分辨率如800X600或1024X768,这些扩充的模式就称之为VESA(Video Electronics Standards Association,视频电子标准协会)的Super VGA模式,简称SVGA,现在的显卡和显示器都支持SVGA模式。

电子设计自动化课程设计报告

图4 VGA接口

VGA接口就是显卡上输出模拟信号的接口,也叫D-Sub接口。VGA接口是一种D型接口,上面共有15针空,分成三排,每排五个。VGA接口是显卡上应用最为广泛的接口类型,绝大多数的显卡都带有此种接口。

表1 VGA管脚定义

管脚定义

1 红基色red

2 绿基色green

3 蓝基色blue

电子设计自动化课程设计报告

通过模拟VGA接口和计算机连接的显示器的工作原理,是计算机内部以数字方式生成的显示图像信息,被显卡中的数字/模拟转换器转变为R、G、B三原色信号和行、场同步信号,信号通过电缆传输到显示设备中。对于模拟显示设备,如模拟CRT显示器,信号被直接送到相应的处理电路,驱动控制显像管生成图像。而对于LCD、DLP等数字显示设备,显示设备中需配置相应的A/D(模拟/数字)

转换器,将模拟信号转变为数字信号。在经过D/A和A/D2次转换后,不可避免地造成了一些图像细节的损失。VGA接口应用于CRT显示器无可厚非,但用于

连接液晶之类的显示设备,则转换过程的图像损失会使显示效果略微下降。CRT 显示器因为设计制造上的原因,只能接受模拟信号输入,也就是我们为什么在CRT显示器上只看到VGA接口的原因。

四、VGA显示接口原理

计算机显示器的显示有许多标准,常见的有VGA、SVGA等。本系统采用FPGA 来实现图像显示控制器,这在产品开发设计中有许多实际应用。

常见的彩色显示器,一般由CRT(阴极射线管)构成,彩色是由G、R、B (绿:Green,红:Red,蓝:Blue)三基色组成。显示是用逐行扫描的方式解决,阴极射线枪发出电子束打在涂有荧光粉的荧光屏上,产生GRB三基色,合成一个彩色像素。扫描从屏幕的左上方开始,从左到右,从上到下,进行扫描,每扫完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行行同步;扫描完所有行,用场同步信号进行场同步,并使扫描回到屏幕的左上方,同时进行场消隐,预备下一场的扫描。

对于普通的VGA显示器,其引出线共含5个信号:G、R、B:三基色信号;HS:行同步信号;VS:场同步信号。

对于5个信号的时序驱动,对于VGA显示器要严格遵循“VGA工业标准”,即640×480×60Hz模式。通常我们用的显示器都满足工业标准,因此我们设计VGA控制器时要参考显示器的技术规格。

图5是VGA行扫描、场扫描的时序图:

电子设计自动化课程设计报告

图5 VGA行扫描、场扫描时序图

电子设计自动化课程设计报告

表2 VGA参考时序设计

VGA工业标准所要求的频率:

时钟频率(Clock frequency):25.175MHz(像素输出的频率);

行频(Line frequency):31469Hz;

场频(Field frequency):59.94Hz(每秒图像刷新频率)。

五、FPGA的设计实现

设计VGA图像显示控制需要注意两个问题:一个是时序的驱动,这是完成设计的关键,时序稍有偏差,显示必然不正常,甚至会损坏彩色显示器;另一个是VGA信号的电平驱动。

显示控制器设计提示:显示器的技术规格提供的行频一般都满足在30-45KHz(保守数据),场频一般满足在50-75Hz(保守数据),针对以上保守数据,我们以30KHz的行频进行扫描时所需时钟频率为:30KHz×800(行周期)=24MHz,则场频为:30KHz÷525(场周期)=57.14Hz,针对实验箱的条件,可以用12MHz的信号经过倍频(EP1K30QC208-2芯片特有的功能,在MaxPlusII软件中调用参数可设置兆功能元件库mega_lpm的CLKLOCK元件来倍频)来产生24MHz的时钟频率,参考设计的顶层文件如下图所示:

电子设计自动化课程设计报告

图6.VGA接口实现顶视图

VGACORE模块包含了扫描时序产生模块、图像描述模块。时序产生模块的设计可参考图5所示来设计,图像描述模块主要通过640×480个像素点来描述图像。如本项设计的彩条信号发生器可通过图像描述模块产生如下表所示的3种显示模式,共6种显示变化的图像。

表3 VGA图形编码

1 行彩条1:白黄青绿品红蓝黑2:黑蓝红品绿青黄白

2 竖彩条1:白黄青绿品红蓝黑2:黑蓝红品绿青黄白

3 棋盘格1:棋盘格显示模式1 2:棋盘格显示模式2

表4 VGA颜色编码

颜色黑蓝红品绿青黄白

G 0 0 0 0 1 1 1 1

R 0 0 1 1 0 0 1 1

B 0 1 0 1 0 1 0 1

在设计完彩条信号发生器的基础上很容易完成汉字/图像的设计。由于本设计是对视频数据进行处理,用普通的设计方法(不使用专用芯片),在单芯片上实现是不可思议的,而在此用FPGA设计,轻松地达到了面积和速度上的要求。

六、程序及仿真

(一)、管脚分配

本设计采用主板上的VGA接口

实验模式:模式5

时钟及控制

clk----->pin_29 clock9 实验要求采用12M的时钟

rst----->pin_240 键8,低电平有效,作为使能信号

MD ----->pin_233 键1,模式选择信号,共有6种模式

显示器输出

R ----->pin_180 PIO29

G ----->pin_181 PIO30

B ----->pin_182 PIO31

HS ----->pin_183 PIO32

VS ----->pin_185 PIO34

(二)、彩条发生器程序实现及仿真

1、主程序

module vga( clk_25m,rst_n, //系统控制

hsync,vsync,vga_rgb,MD // VGA控制

);

input clk_25m; // 25MHz

input rst_n; //低电平复位

input MD;

// FPGA与VGA接口信号

output hsync; //行同步信号

output vsync; //场同步信号

output[2:0] vga_rgb;

//-------------------------------------------------- // 坐标计数

reg[9:0] x_cnt; //行坐标

reg[9:0] y_cnt; //列坐标

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) x_cnt <= 10'd0;

else if(x_cnt == 10'd799) x_cnt <= 10'd0;

else x_cnt <= x_cnt+1'b1;

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) y_cnt <= 10'd0;

else if(y_cnt == 10'd524) y_cnt <= 10'd0;

else if(x_cnt == 10'd799) y_cnt <= y_cnt+1'b1;

//-------------------------------------------------- // 产生VGA场同步,行同步信号

reg hsync_r,vsync_r;

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) hsync_r <= 1'b1;

else if(x_cnt == 10'd0) hsync_r <= 1'b0; //产生hsync信号else if(x_cnt == 10'd96) hsync_r <= 1'b1;

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) vsync_r <= 1'b1;

else if(y_cnt == 10'd0) vsync_r <= 1'b0; //产生vsync信号else if(y_cnt == 10'd2) vsync_r <= 1'b1;

assign hsync = hsync_r;

assign vsync = vsync_r;

//-------------------------------------------------- //有效显示标志位产生

reg valid_yr; //行显示有效信号

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) valid_yr <= 1'b0;

else if(y_cnt == 10'd32) valid_yr <= 1'b1;

else if(y_cnt == 10'd512) valid_yr <= 1'b0;

wire valid_y = valid_yr;

reg valid_r; // VGA有效显示区标志位

always @ (posedge clk_25m or negedge rst_n)

if(!rst_n) valid_r <= 1'b0;

else if((x_cnt == 10'd141) && valid_y) valid_r <= 1'b1;

else if((x_cnt == 10'd781) && valid_y) valid_r <= 1'b0;

wire valid = valid_r;

wire[9:0] x_dis; //横坐标显示有效区域相对坐标值0-639 wire[9:0] y_dis; //竖坐标显示有效区域相对坐标值0-479

assign x_dis = x_cnt - 10'd142;

assign y_dis = y_cnt - 10'd33;

//-------------------------------------------------- //---------------------------------------------

reg[2:0] cnt;

always @ (posedge MD or negedge rst_n) begin

if(!rst_n)

cnt <= 3'd0;

else if(cnt==3'd5)

cnt<=3'd0;

else

cnt<=cnt+3'd1;

end

//-------------------------------------------------- // VGA色彩信号产生

/*

RGB = 000 黑色RGB = 100 红色

= 001 蓝色= 101 紫色

= 010 绿色= 110 黄色

= 011 青色= 111 白色

*/

//---------------------------------------------------- reg[2:0] vga_rgb;

always@( posedge clk_25m)begin

if(!valid) vga_rgb <= 3'd0;

else begin

if (cnt==3'd0)begin //竖彩条模式

if(x_dis >= 10'd0 && x_dis < 10'd80) vga_rgb <= 3'd0;

else if(x_dis >= 10'd80 && x_dis < 10'd160) vga_rgb <= 3'd1;

else if(x_dis >= 10'd160 && x_dis < 10'd240) vga_rgb <= 3'd2;

else if(x_dis >= 10'd240 && x_dis < 10'd320) vga_rgb <= 3'd3;

else if(x_dis >= 10'd320 && x_dis < 10'd400) vga_rgb <= 3'd4;

else if(x_dis >= 10'd400 && x_dis < 10'd480) vga_rgb <=3'd5;

else if(x_dis >= 10'd480 && x_dis < 10'd560) vga_rgb <= 3'd6;

else if(x_dis >= 10'd560 && x_dis < 10'd640) vga_rgb <= 3'd7;

end

if (cnt==3'd1)begin //竖彩条模式

if(x_dis >= 10'd0 && x_dis < 10'd80) vga_rgb <= 3'd7;

else if(x_dis >= 10'd80 && x_dis < 10'd160) vga_rgb <= 3'd6;

else if(x_dis >= 10'd160 && x_dis < 10'd240) vga_rgb <= 3'd5;

else if(x_dis >= 10'd240 && x_dis < 10'd320) vga_rgb <= 3'd4;

else if(x_dis >= 10'd320 && x_dis < 10'd400) vga_rgb <= 3'd3;

else if(x_dis >= 10'd400 && x_dis < 10'd480) vga_rgb <=3'd2;

else if(x_dis >= 10'd480 && x_dis < 10'd560) vga_rgb <= 3'd1;

else if(x_dis >= 10'd560 && x_dis < 10'd640) vga_rgb <= 3'd0;

end

if(cnt==3'd2)begin //横彩条模式

if(y_dis >= 10'd0 && y_dis < 10'd60) vga_rgb <= 3'd0;

else if(y_dis >= 10'd60 && y_dis < 10'd120) vga_rgb <= 3'd1;

else if(y_dis >= 10'd120 && y_dis < 10'd180) vga_rgb <= 3'd2;

else if(y_dis >= 10'd180 && y_dis < 10'd240) vga_rgb <= 3'd3;

else if(y_dis >= 10'd240 && y_dis < 10'd300) vga_rgb <= 3'd4;

else if(y_dis >= 10'd300 && y_dis < 10'd360) vga_rgb <= 3'd5;

else if(y_dis >= 10'd360 && y_dis < 10'd420) vga_rgb <= 3'd6;

else if(y_dis >= 10'd420 && y_dis < 10'd480) vga_rgb <=3'd7;

end

if(cnt==3'd3)begin //横彩条模式

if(y_dis >= 10'd0 && y_dis < 10'd60) vga_rgb <= 3'd7;

else if(y_dis >= 10'd60 && y_dis < 10'd120) vga_rgb <= 3'd6;

else if(y_dis >= 10'd120 && y_dis < 10'd180) vga_rgb <= 3'd5;

else if(y_dis >= 10'd180 && y_dis < 10'd240) vga_rgb <= 3'd4;

else if(y_dis >= 10'd240 && y_dis < 10'd300) vga_rgb <= 3'd3;

else if(y_dis >= 10'd300 && y_dis < 10'd360) vga_rgb <= 3'd2;

else if(y_dis >= 10'd360 && y_dis < 10'd420) vga_rgb <= 3'd1;

else if(y_dis >= 10'd420 && y_dis < 10'd480) vga_rgb <=3'd0; end

if(cnt==3'd4)begin //棋盘格模式

case(x_dis)

10'd0: begin

if(y_dis >= 10'd0 && y_dis < 10'd60) vga_rgb <= 3'd0;

else if(y_dis >= 10'd60 && y_dis < 10'd120) vga_rgb <= 3'd1;

else if(y_dis >= 10'd120 && y_dis < 10'd180) vga_rgb <= 3'd2;

else if(y_dis >= 10'd180 && y_dis < 10'd240) vga_rgb <= 3'd3;

else if(y_dis >= 10'd240 && y_dis < 10'd300) vga_rgb <= 3'd4;

else if(y_dis >= 10'd300 && y_dis < 10'd360) vga_rgb <= 3'd5;

else if(y_dis >= 10'd360 && y_dis < 10'd420) vga_rgb <= 3'd6;

else if(y_dis >= 10'd420 && y_dis < 10'd480) vga_rgb <= 3'd7;

end

10'd80,10'd160,10'd240,10'd320,10'd400,10'd480,10'd560,10'd640:

vga_rgb <= vga_rgb+3'd1; //每80个横坐标像素点后显示色彩数据增1变化

default: ;

endcase

end

if(cnt==3'd5)begin //棋盘格模式

case(x_dis)

10'd0: begin

if(y_dis >= 10'd0 && y_dis < 10'd60) vga_rgb <= 3'd7;

else if(y_dis >= 10'd60 && y_dis < 10'd120) vga_rgb <= 3'd6;

else if(y_dis >= 10'd120 && y_dis < 10'd180) vga_rgb <= 3'd5;

else if(y_dis >= 10'd180 && y_dis < 10'd240) vga_rgb <= 3'd4;

else if(y_dis >= 10'd240 && y_dis < 10'd300) vga_rgb <= 3'd3;

else if(y_dis >= 10'd300 && y_dis < 10'd360) vga_rgb <= 3'd2;

else if(y_dis >= 10'd360 && y_dis < 10'd420) vga_rgb <= 3'd1;

else if(y_dis >= 10'd420 && y_dis < 10'd480) vga_rgb <= 3'd0;

end

10'd80,10'd160,10'd240,10'd320,10'd400,10'd480,10'd560,10'd640:

vga_rgb <= vga_rgb+3'd1; //每80个横坐标像素点后显示色彩数据增1变化

default: ;

endcase

end

end

end

endmodule

2、验证程序

`timescale 1 ns/ 1 ps

module tb_vga ();

reg t_clk_25m;

reg t_rst_n;

wire t_hsync;

wire [2:0] t_vga_rgb;

wire t_vsync;

wire t_MD;

vgahct dut( .clk_25m(t_clk_25m),

.hsync(t_hsync),

.rst_n(t_rst_n),

.vga_rgb(t_vga_rgb),

.vsync(t_vsync),

.MD(t_MD)

);

initial

begin

t_clk_25m=0;

t_rst_n=1;

t)MD=0;

#20;

t_rst_n=0;

#50;

t_rst_n=1;

$display("Running testbench");

#10000000000 $stop;

end

always #0.04 t_clk_25m=~t_clk_25m;

always #200 t_MD=~t_MD;

endmodule

3、仿真波形