VGA协议与图像输出Verilog编程
1、实验3-基于Verilog HDL的数字秒表
准备工作:
1.建立工程
2.添加文件选择verilog
3.主要代码
module n_clk_top(
input clk,
input reset,
input pause,
output reg [3:0] msh, //百秒十位
output reg [3:0] msl, //百秒个位
output reg [3:0] sh, //秒十位
output reg [3:0] sl, //秒个位
output reg [3:0] minh, //分十位
output reg [3:0] minl //分个位
);
reg count1,count2;
//百分秒计数
always @(posedge clk or posedge reset)
begin
if(reset)
begin
{msh,msl}<=0;
count1<=0;
end
else if(!pause)
begin
if(msl==9)
begin
msl<=0;
if(msh==9)
begin
msh<=0;
count1<=1;
end
else
msh<=msh+1;
end
else
begin
msl<=msl+1;
count1<=0;
end
end
end
//秒计数
always@(posedge count1 or posedge reset)begin
if(reset)
begin
{sh,sl}<=0;
count2<=0;
end
else if(sl==9)
begin
sl<=0;
if(sh==5)
begin
sh<=0;
count2<=1;
end
else
sh<=sh+1;
end
else
begin
sl<=sl+1;
count2<=0;
end
end
//分计数
always @(posedge count2 or posedge reset)
begin
if(reset)
begin
minh<=0;
minl<=0;
end
else if(minl==9)
begin
minl<=0;
if(minh==5)
minh<=0;
else
minh<=minh+1;
end
else
minl<=minl+1;
end
endmodule
4.仿真 VWF波形文件
仿真事件设置10s
结果显示
2、练习基于VGA的图像显示,了解VGA协议,通过Verilog编程实现VGA端口生成彩条图案或者自定义的汉字图案
①.FPGA驱动VGA图像显示
1.生成汉字点阵
2.生成字模数组
数组代码:
{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",0*/
{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",1*/
2.Verilog
时序图像:
代码块:
`define HSYNC_A 16'd128
`define HSYNC_B 16'd216
`define HSYNC_C 16'd1016
`define HSYNC_D 16'd1056
`define VSYNC_O 16'd4
`define VSYNC_P 16'd27
`define VSYNC_Q 16'd627
`define VSYNC_R 16'd628
`define RED 8'hE0
`define GREEN 8'h1C
`define BLUE 8'h03
`define YELLOW 8'hFC
`define BLACK 8'h00
module VGA
(
//输入
input CLK_50M,
input RST_N,
//输出
output reg VSYNC,
output reg HSYNC,
output reg[7:0] VGA_DATA
);
reg[15:0] hsync_cnt;
reg[15:0] vsync_cnt;
reg vga_data_valid;
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
hsync_cnt <= 16'd0;
else if(hsync_cnt == `HSYNC_D)
hsync_cnt <= 16'd0;
else
hsync_cnt <= hsync_cnt + 16'd1;
end
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
vsync_cnt <= 16'd0;
else if((vsync_cnt == `VSYNC_R) && (hsync_cnt == `HSYNC_D))
vsync_cnt <= 16'd0;
else if(hsync_cnt == `HSYNC_D)
vsync_cnt <= vsync_cnt + 16'd1;
else
vsync_cnt <= vsync_cnt;
end
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
HSYNC <= 1'b0;
else if(hsync_cnt < `HSYNC_A)
HSYNC <= 1'b0;
else
HSYNC <= 1'b1;
end
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
VSYNC <= 1'b0;
else if(vsync_cnt < `VSYNC_O)
VSYNC <= 1'b0;
else
VSYNC <= 1'b1;
end
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
vga_data_valid <= 1'b0;
else if((hsync_cnt > `HSYNC_B && hsync_cnt < `HSYNC_C) && (vsync_cnt > `VSYNC_P && vsync_cnt < `VSYNC_Q)
vga_data_valid <= 1'b1;
else
vga_data_valid <= 1'b0;
end
reg [7:0] rom_add;
wire [15:0] rom_data;
wire [15:0] vga_x;
wire [15:0] vga_y;
assign vga_x = hsync_cnt - `HSYNC_B;
assign vga_y = vsync_cnt - `VSYNC_P;
assign display_en = (vga_x >= 10'd98) && (vga_x <= 10'd116) && (vga_y >= 10'd90) && (vga_y <= 10'd106);
always@(posedge CLK_40M or negedge RST_N)
begin
if(!RST_N)
rom_add <= 8'h0;
else if(display_en)
begin
if(vga_x == 10'd98)
rom_add <= 8'h0;
else if(vga_x == 10'd106)
rom_add <= 8'h08;
else
rom_add <= rom_add + 1'b1;
end
else
rom_add <= 8'h0;
end
always@(*)
begin
if(display_en)
begin
if(rom_data[10'd106 - vga_y]
VGA_DATA <= `RED;
else
VGA_DATA <= `YELLOW;
end
else
VGA_DATA <= `BLACK;
end
ROM ROM_inst (
.address ( rom_add ),
.clock ( CLK_40M ),
.q ( rom_data )
);
wire CLK_40M;
PLL PLL_inst (
.inclk0 ( CLK_50M ),
.c0 ( CLK_40M )
);
endmodule
结果展示: