VGA协议与图像输出Verilog编程

一、学习任务

1、从"实验3-基于Verilog HDL的数字秒表、波形发生器等设计" 任选一个完成;
2、练习基于VGA的图像显示,了解VGA协议,通过Verilog编程实现VGA端口生成彩条图案或者自定义的汉字图案;或者完成一个简单的类似贪吃蛇的VGA小游戏 (实际效果验证可在下次实验课检查)。

二、学习内容

1.基于Verilog HDL的数字秒表

1.1.仿真波形

1.1.1.异步复位功能

1.reset从1变为0时,hofs,sec,minute全被复位变成0.
在这里插入图片描述
2.reset从0变为1后,hofs重新计数
在这里插入图片描述

1.1.2.暂停功能

1.stop从0变为1时,hofs,sec,minute保持不变。
在这里插入图片描述
2.stop从1变成0,hofs,sec,minute继续计数。
在这里插入图片描述

1.1.3.计数功能

1.hofs从0计数到99,sec加一次。
在这里插入图片描述
2.sec从0计数到59,minute加一次。
在这里插入图片描述
3.minute从0计数到59,hofs,sec,minute全部清0,重新下一次的计数
在这里插入图片描述

1.2.相关代码

module stopwatch(
  input                      clk,
  input                      rst_n,
  input                      stop,
  output [5:0]               minute,
  output [5:0]               sec,
  output [6:0]               hofs
  );
  reg    [6:0]               counter100;//模100的计数器,用于百分秒计数和进位
  reg    [5:0]               counter60_s; //模60的计数器,用于秒计数和进位
  reg    [5:0]               counter60_m;//模60的计数器,用于分计数和清零
  //异步复位和暂停
  // counter100
  always@(posedge clk or negedge rst_n or posedge stop) begin
    if(!rst_n)  //复位功能,低电平有效
        counter100 <= 7'b0000000;
    else if(stop) //暂停功能,高电平有效,保持原值不变
        counter100 <= counter100;
    else if(counter100 < 7'b1100011)//实现模100的计数器,小于99,累加1
        counter100 <= counter100 + 1'b1;
    else
        counter100 <= 7'b0000000;
   end

 //  counter60_s
  always@(posedge clk or negedge rst_n or posedge stop) begin
    if(!rst_n)  //复位功能,低电平有效
         counter60_s <= 6'b000000;
    else if(stop) //暂停功能,高电平有效,保持原值不变
         counter60_s <= counter60_s;
    else 
         if(counter60_s < 6'b111100)
           if(counter100 == 7'b1100011)
              counter60_s <= counter60_s + 1'b1;
           else
              counter60_s <= counter60_s;
    else
        counter60_s <= 6'b000000;
   end

 // counter60_m
  always@(posedge clk or negedge rst_n or posedge stop) begin
    if(!rst_n)  //复位功能,低电平有效
         counter60_m <= 6'b000000;
    else if(stop) //暂停功能,高电平有效,保持原值不变
        counter60_m <= counter60_m;
    else if(counter60_m < 6'b111100) 
              if((counter60_s == 6'b111011)&&(counter100 == 7'b1100011))
                    counter60_m <= counter60_m + 1'b1;
              else
                    counter60_m <= counter60_m ;
    else
        counter60_m <= 6'b000000;
   end
   //将对应模的计数器赋值给对应的百分秒、秒、分钟
  assign hofs = counter100;
  assign sec = counter60_s;
  assign minute = counter60_m;
endmodule
`timescale 1ns / 1ns
module stopwatch_tb();
  parameter  CYCLE        = 10;//100MHz
  reg                        clk;
  reg                        rst_n;//更改reset为rst_n
  reg                        stop;
  wire [6:0]                 hofs;
  wire [6:0]                 counter100;
  wire [5:0]                 minute;
  wire [5:0]                 sec;
  wire [5:0]                 counter60_s;
  wire [5:0]                 counter60_m;

  always #(CYCLE/2) clk = ~clk;
  initial begin
            clk            = 1'b0;
            rst_n          = 1'b0;
            stop           = 1'b0;
            #(CYCLE*5)
            rst_n          = 1'b1;
            stop           = 1'b0;
            #(CYCLE*120)
            rst_n          = 1'b1;
            stop           = 1'b1;
            #(CYCLE*5)
            rst_n          = 1'b1;
            stop           = 1'b0;
            #(CYCLE*37000)
            rst_n          = 1'b0;
            stop           = 1'b0;
             #(CYCLE*5)
            rst_n          = 1'b1;
            stop           = 1'b0;
            #(CYCLE*37000)
            rst_n          = 1'b1;
            stop           = 1'b0;
            #(CYCLE*10000)
            $stop;
   end

stopwatch U1(.clk(clk),
             .rst_n(rst_n),
             .stop(stop),
             .minute(minute),
             .sec(sec),
             .hofs(hofs));

endmodule

2.基于VGA的图像显示

1.FPGA驱动VGA显示文字

1.1.生成字库

取模格式设置:
在这里插入图片描述
字模数组生成:
在这里插入图片描述
生成的数组:

{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*/
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
1.3.结果显示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值