FPGA|VGA的8色彩条的实现

VGA显示8色彩条的实现

使用软件:Quartus II 13.1
使用语言 :Verilog HDL
板载芯片:EP4CE6E22C8

写在前面

由于之前在学校学习的FPGA基础是基于VHDL(Very-High-Speed Integrated Circuit Hardware Description Language)的,但大都已经忘记不太想从头再来,所以再次学习并接触FPGA,想用另一种更接近C语言的HDL(硬件描述语言)–也就是Verilog HDL。

VHDL有entity(实体),architecture(结构体)configuration(配置)package(包),和library(库)

  • entity内部主要包括端口的声明,建立一个黑盒子的模型。

  • architecture内部主要包括行为级的内部逻辑设计,进行各个进程或状态机的配置。

  • library 用于引用所需要的库文件。常使用库文件library ieee;

  • package用于引用需要的包文件。例如,如果要使用std_logic(标准逻辑)类型,应对类型所在包进行声明use ieee.std_logic_1164.all;,否则会报错;如果行为级建模是需要运算符重载,则要声明use ieee.std_logic_unsigned.all,如果需要类型转换从整型转化为逻辑矢量类型的函数CONV_STD_LOGIC_VECTOR(begin,end),则需要引用use ieee.std_logic_arith.all

当然与VHDL 类似的 ,Verilog HDL 也有着类似的结构,比如module(模块)procedural(过程块) `include(头文件)对应 于 VHDLportprocess,package。所以如果有C语言和VHDL语言的基础,VerilogHDL是不成问题的。

准备工作

书归正传,了解了使用语言的语法有利于代码的编写和代码的阅读。

我们应该再了解一下VGA相关的知识。

VGA接口

VGA接口是一种D型接口,采用非对称分布连接方式,共有15针.对用户来说,其引出线常用的有5个信号:红色 R,绿色 G,蓝色B,行同步信号HS,场同步信号 VS.HS和 VS的作用是处理输入模拟信号,并联合起来控制VGA的显示时序,分别对应PIN1、PIN2、PIN3、PIN13、PIN14。

是不是有点抽象?这边上图最为直接明了
在这里插入图片描述

当然,美术生和 Photoshop使用者应该对色彩不会太陌生,Red、Green、Blue正是三原色,经过不同的混合碰撞,产生色彩缤纷的世界,进而显示再屏幕上,但是硬件内部实现输出的是数字信号,无法被显示在VGA显示屏上,因而需要进行数模转换DAC(Digital Analog Convertor),常用的数模转换芯片是ADV7125,是3个8位视频信号的DAC信号的转换。
在这里插入图片描述

但是,芯片开销会比较大,所以一般VGA视频图像信号都使用权电阻网络(如下图所示)来完成
在这里插入图片描述
R s = 8 R {R_s = 8R } Rs=8R, V o = − V r e f 2 8 D n {V_o = -\frac{V_{ref}}{2^8}D_n} Vo=28VrefDn, D n 是 高 位 ( M S B ) 或 低 位 ( L S B ) 电 阻 权 重 {D_n}是高位(MSB)或低位(LSB)电阻权重 Dn(MSB)LSB

VGA 时序

了解了VGA接口的相关知识,进一步了解一下VGA时序的知识,因为书写代码一般是以时序为准。以一般工业标准来说,640*480@60是显示比较稳定且易于掌握的,因而下文皆是根据640*480@60讲述的。
@Attention:640*480@60,表示行列总共有307200个像素点,同时显示一帧图像的速率是60MHz
在这里插入图片描述
由上图可知行扫描周期以像素为单位,分别由行同步、后沿、图像有效区域、前沿直到下一帧图像开始,当完成一行的扫描后,场扫描周期开始,同时经过场同步、上沿,图像有效区域、下沿构成。

开始Coding

根据前面的讲解应该对VGA显示有所了解,因而开始Coding。

/*
* @author: LangZi
* @data:2021.12.26
* @modulename:VGA
* @header:include"vga_param.v"
*/
`include"vga_param.v"
module VGA(
clock	,
switch	,
out_RGB	,
hsync	,
vsync
);
input  clock		;    //系统时钟 50MHz
input  [1:0] switch	;	//用于切换模式,显示棋盘格

output [2:0] out_RGB;   //VGA输出颜色
output  hsync		;   //VGA扫描信号
output  vsync		;   //VGA场扫描信号

reg [9:0]    hcount	;   //VGA行计数器
reg [9:0]    vcount	;  //VGA场计数器
reg [2:0]    data		;
reg [2:0]    h_dat		;
reg [2:0]    v_dat		;

reg   flag				;	//标志位
wire  hcount_ov			; 	//溢出信号
wire  vcount_ov			;
wire  dat_act			;
wire  hsync				;
wire  vsync				;
reg  vga_clk			;

//分频操作活得25MHz的时钟
always @(posedge clock)
begin
vga_clk = ~vga_clk;
end

//************************VGA驱动******************************* 
//行计数
always @(posedge vga_clk)
begin
if (hcount_ov)// 若溢出则清零
hcount <= 10'd0;
else
hcount <= hcount + 10'd1;
end
assign hcount_ov = (hcount == hpixel_end);
//场计数
always @(posedge vga_clk)
begin
if (hcount_ov)
begin
if (vcount_ov)
vcount <= 10'd0;
else
vcount <= vcount + 10'd1;
end
end
assign  vcount_ov = (vcount == vline_end);
//判断是否处于有效数据区域
assign dat_act =    ((hcount >= hdat_begin) && (hcount < hdat_end))
&& ((vcount >= vdat_begin) && (vcount < vdat_end));
assign hsync = (hcount > hsync_end);
assign vsync = (vcount > vsync_end);
assign disp_RGB = (dat_act) ?  data : 3'h00;       

//************************VGA 显示处理操作******************************* 
always @(posedge vga_clk)
begin
case(switch[1:0])
2'd0: data <= h_dat;      //行数据
2'd1: data <= v_dat;      //列数据
2'd2: data <= (v_dat ^ h_dat); //棋盘格
2'd3: data <= (v_dat ~^ h_dat); //转置棋盘
endcase
end

always @(posedge vga_clk)  //行彩条计数时序
begin
if(hcount < 223)
v_dat <= 3'h7;         
else if(hcount < 303)
v_dat <= 3'h6;   
else if(hcount < 383)
v_dat <= 3'h5;   
else if(hcount < 463)
v_dat <= 3'h4;    
else if(hcount < 543)
v_dat <= 3'h3;   
else if(hcount < 623)
v_dat <= 3'h2;   
else if(hcount < 703)
v_dat <= 3'h1;   
else 
v_dat <= 3'h0;   
end

always @(posedge vga_clk)  //列彩条计数时序
begin
if(vcount < 94)
h_dat <= 3'h7;        
else if(vcount < 154)
h_dat <= 3'h6;   
else if(vcount < 214)
h_dat <= 3'h5;   
else if(vcount < 274)
h_dat <= 3'h4;    
else if(vcount < 334)
h_dat <= 3'h3;   
else if(vcount < 394)
h_dat <= 3'h2;   
else if(vcount < 454)
h_dat <= 3'h1;   
else 
h_dat <= 3'h0;   
end

endmodule

时序参数的头文件(vga_param.v)

`ifndef __VGA_PARAM_
`define __VGA_PARAM_640_480_60MHz
`define hsync_end    10'd95
`define hdat_begin   10'd143
`define hdat_end     10'd783
`define hpixel_end   10'd799
`define vsync_end 	 10'd1
`define vdat_begin   10'd34
`define vdat_end     10'd514
`define vline_end  	 10'd524
`endif

引入头文件,可以提升代码的可移植性,同时可以将文件的代码风格显示的更简洁,易懂

结果显示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

写在最后

FPGA的首篇作文,尚有不足,愿共勉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值