【VGA 与 UART 通信的联合使用】

VGA 与 UART 通信的联合使用

基础:
由 PC 通过 UART 发送数据在 VGA 显示。数据可以为字母,数字,汉字,VGA 分为左右两个区域,输入字母或者数字时在VGA 右边显示,输入汉字时在 VGA 左边显示。
发挥:
有删除功能,可通过按键删除显示的数字,字母或者汉字。左边的按键按下字母或者数字删除,右边的按键按下汉字删除。每次仅可删除一个字符。举例:VGA 左侧显示 FPGA 时,按下左边的键,VGA显示 FPG,再按一下,显示 FP。
注:板子为国产安陆板子,时钟周期为24Mhz

Top-Down设计思想

顶层模块负责各个模块信号互连;分频模块通过调用PLL实现倍频;rx模块接收上位机发送的数据并根据按键按下的情况产生标志位;Drive模块通过rx模块产生的标志位控制vga的显示;key用来对按键进行消抖。

顶层模块

module uart_top
(
	input 	wire	ext_clk_25m,	//输入时钟
	input 	wire	ext_rst_n,		//复位
	input	wire 			rx,
	output wire			vga_clk,	//lcd pixel clock			
	output wire			vga_hs,		//lcd horizontal sync 
	output wire			vga_vs,		//lcd vertical syn
	output wire [7:0]  	vga_r,		//lcd red data
	output wire [7:0]	vga_g,		//lcd green data
	output wire [7:0]	vga_b,	//lcd blue data
	input wire			key,   
	input wire			key2,
	output wire 	[3:0]led,
	output wire [3:0]led1
);												

//-------------------------------------
wire clk_25m;	//PLL
wire clk_50m;	//PLL
wire clk_100m;	//PLL
wire sys_rst_n;	//
//-------------------------------------
wire 		flag;
wire [7:0]	data;
wire	clk_vga;
wire  flag_FPGA,flag_geng,key_flag,flag_FPG,key2_flag,flag_zhou,flag_h0;
//sync global clock and reset signal 
key_debounce inst
(
	.clk(clk_50m),
	.rst_n(sys_rst_n),
	.key(key),
	.key2(key2),
	.led(led),
	.key_flag(key_flag),
	.key2_flag(key2_flag)
);
//输出180Mhz的时钟供vga使用
pll_vga u_pll
(
	.refclk		    (ext_clk_25m	),
	.reset		    (~ext_rst_n		),
	.extlock	    (sys_rst_n1	),
	.clk0_out	    (clk_vga	)
);
//VGA driver timing
Driver u1_Driver
(
	.clk			(clk_vga				),		//180mhz
	.clk1(clk_50m),
	.rst_n			(sys_rst_n1				),  
	.lcd_dclk		(vga_clk				),		    	
	.lcd_hs			(vga_hs					),		
	.lcd_vs			(vga_vs					),	
	.lcd_rgb		({vga_r, vga_g ,vga_b}	),
	.flag_FPGA(flag_FPGA),
	.flag_geng(flag_geng),
	.flag_FPG(flag_FPG),
	.flag_FP(flag_FP),
	.flag_F(flag_F),
	.flag_0(flag_0),
	.flag_zhou(flag_zhou),
	.flag_h0(flag_h0)
);
	uart_rx  inst_uart_rx (
			.sclk    (clk_50m),
			.rst_n   (sys_rst_n),
			.rx      (rx),
			.po_data (data),
			.po_flag (flag),
			.flag_FPGA(flag_FPGA),
			.flag_geng(flag_geng),
			.key_flag(key_flag),
			.key2_flag(key2_flag),
			.flag_FPG(flag_FPG),
			.led(led1),
			.flag_FP(flag_FP),
			.flag_F(flag_F),
			.flag_0(flag_0),
			.flag_zhou(flag_zhou),
        	.flag_h0(flag_h0)
		);
//PLL
pll_test u_pll_test
(
	.refclk		    (ext_clk_25m	),
	.reset		    (~ext_rst_n		),
	.extlock	    (sys_rst_n		),
	.clk0_out	    (clk_25m		),
	.clk1_out	    (clk_50m		),
	.clk2_out	    (clk_100m		)
);
endmodule

rx模块:

module uart_rx(
	input	wire 				sclk,
	input	wire 				rst_n,
	input	wire 				rx,
	input   wire                key_flag,
    input   wire                key2_flag,
	output	reg 	[7:0]		po_data,
	output	reg 				po_flag,
	output reg flag_FPGA,
	output reg flag_geng,
	output reg flag_FPG,
	output reg flag_FP,
	output reg flag_F,
	output reg flag_0,
	output reg		flag_zhou,
	output reg 		flag_h0,
	output reg [3:0]led
	);

parameter 	CNT_BAUD_MAX = 5207;
parameter	CNT_HALF_BAUD_MAX = 2603;
reg 			rx1,rx2,rx2_reg;
reg 			rx_flag;
reg 	[12:0]	cnt_baud;
reg 			bit_flag;
reg 	[3:0]	bit_cnt;
reg [31:0]str;
always @(posedge sclk) begin
	{rx2_reg,rx2,rx1}<={rx2,rx1,rx};
end

//接收上位机传来的数据
always @(posedge sclk or negedge  rst_n) begin
	if (rst_n == 1'b0) begin
		rx_flag <= 1'b0;
	end
	else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
		rx_flag <= 1'b0;
	end
	else if (rx2_reg == 1'b1 && rx2 == 1'b0) begin
		rx_flag <= 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b0) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b1 && cnt_baud == CNT_BAUD_MAX) begin
		cnt_baud <= 'd0;
	end
	else if (rx_flag == 1'b1) begin
		cnt_baud <= cnt_baud + 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_flag <= 1'b0;
	end
	else if (rx_flag == 1'b1 && cnt_baud == CNT_HALF_BAUD_MAX) begin
		bit_flag <= 1'b1;
	end
	else begin
		bit_flag <= 1'b0;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		bit_cnt <= 'd0;
	end
	else if (bit_flag == 1'b1 && bit_cnt == 'd8) begin
		bit_cnt <= 'd0;
	end
	else if (bit_flag == 1'b1) begin
		bit_cnt <= bit_cnt + 1'b1;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		po_data <='d0;
	end
	else if (bit_cnt >= 4'd1 && bit_flag == 1'b1) begin
		po_data <= {rx2_reg,po_data[7:1]};
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		po_flag <= 1'b0;
	end
	else if (bit_cnt == 4'd8 && bit_flag == 1'b1) begin
		po_flag <= 1'b1;
	end
	else begin
		po_flag <= 1'b0;
	end
end

//根据按键控制标志位,key=1代表按键按下
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_FPGA <= 1'b0;
	end
	else if (str=="FPGA") begin
		flag_FPGA <= 1'b1;
	end
	else begin
		flag_FPGA <= 1'b0;
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_FPG <= 1'b0;
	end
	else if (str=="FPGA"&&key_flag==1) begin
		flag_FPG <= 1'b1;
	end
	else 
		flag_FPG <= 1'b0;
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_FP <= 1'b0;
	end
	else if (str=="FPG"&&key_flag==1) begin
		flag_FP <= 1'b1;
	end
	else 
		flag_FP <= 1'b0;
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_F<= 1'b0;
	end
	else if (str=="FP"&&key_flag==1) begin
		flag_F <= 1'b1;
	end
	else 
		flag_F <= 1'b0;
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_0<= 1'b0;
	end
	else if (str=="F"&&key_flag==1) begin
		flag_0 <= 1'b1;
	end
	else 
		flag_0 <= 1'b0;
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_geng <= 1'b0;
	end
	else if (str==32'b10111001101000101101011011011100)  //汉字,一个汉字用2个8bit数据拼成
	begin
		flag_geng <= 1'b1;
	end
	else begin
		flag_geng <= 1'b0;
	end
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_zhou <= 1'b0;
	end
	else if (str==32'b10111001101000101101011011011100&&key2_flag==1) begin
		flag_zhou <= 1'b1;
	end
	else 
		flag_zhou <= 1'b0;
end
always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		flag_h0 <= 1'b0;
	end
	else if (str==32'b1011100110100010&&key2_flag==1) begin
		flag_h0 <= 1'b1;
	end
	else 
		flag_h0 <= 1'b0;
end

//根据接收到的字符和按键情况产生字符串
always @(posedge sclk or negedge rst_n)
begin
	if (rst_n == 1'b0) begin	
		str <= 0;
	end
		else if (po_flag==1)  //每接收完8bit数据,存入str低8位中
		str <= {str[23:0],po_data};
	else if (key_flag==1) begin   //此按键控制字符删除,按键按下时str高8位赋0
		str <= {8'b0,str[31:8]};
	end
	else if (key2_flag==1) begin      //此按键控制汉字删除,按键按下时str高16位赋0
		str <= {16'b0,str[31:16]};
	end
end

always @(posedge sclk or negedge rst_n) begin
	if (rst_n == 1'b0) begin	
		led <= 4'b1111;
	end
	else if (flag_FPG==1)
	 led[0]<=0;
	 else  led[0]<=1;
end
endmodule 

Drive模块:

`timescale 1ns/1ns
/* 
************	clk		 	H_SYNC 		H_BACK 		H_DISP 		H_FRONT 	H_TOTAL 		V_SYNC 		V_BACK 		V_DISP 		V_FRONT 	V_TOTAL		*
640x480@60Hz	25.2MHz		96			48 			640 		16 			800 			2			33			480 		10			525		*
800x600@60Hz	40MHz		128			88 			800 		40 			1056			4			23			600 		1			628		*
1024x768@60Hz	65MHz		136			160 		1024 		24 			1344			6			29			768 		3			806		*
1280x720@60Hz	74.25MHz	40			220 		1280 		110			1650			5			20			720 		5			750		*
1280x1024@60Hz	108MHz		112			248 		1280 		48 			1688			3			38			1024		1			1066	*
1920x1080@60Hz	148.5MHz	44			148 		1920 		88 			2200			5			36			1080		4			1125	*
*/	
module Driver
#(
	parameter H_SYNC = 112	, 		
	parameter H_BACK = 248	, 		
	parameter H_DISP = 1280	, 		
	parameter H_DISP_half = 640	,
	parameter H_FRONT = 48	, 		
	parameter H_TOTAL = 1688, 		
	parameter V_SYNC = 3	, 		
	parameter V_BACK = 38	, 		
	parameter V_DISP = 1024	, 		
	parameter V_FRONT = 1	, 	
	parameter V_TOTAL = 1066  		
)
(
	input  wire			clk,			//VGA clock
	input  wire			rst_n,     		//sync reset
	input  wire			clk1,
	input  wire		flag_FPGA,
	input  wire		flag_geng,
	input  wire		flag_FPG,
	input  wire		flag_FP,
	input  wire		flag_F,
	input  wire		flag_0,
	input  wire		flag_zhou,
	input  wire		flag_h0,
	output wire			lcd_dclk,   	//lcd pixel clock
	output wire			lcd_hs,	    	//lcd horizontal sync
	output wire			lcd_vs,	//lcd vertical sync
	output reg	[23:0]	lcd_rgb		//lcd display data
);

localparam	weight =10'd16 ; //显示图像的宽
localparam	hight =10'd16 ; //显示图像的高
reg [11:0] hcnt; 
reg [11:0] vcnt;
reg [255:0]char[5:0]; //16*16=256个像素
reg [8:0]cnt_z;
reg [8:0]cnt_z2;
reg [8:0]cnt_y;
reg [8:0]cnt_y2;
reg [8:0]cnt_y3;
reg [8:0]cnt_y4;
//wire lcd_request;
/*******************************************
		SYNC--BACK--DISP--FRONT
*******************************************/ 
//根据标志位控制char[4:0]的赋值,需要删除时将对应的char赋值为0,显示时赋值为对应的字模
always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[0]<=0;
		end
	else if(flag_FPG==1||flag_FPGA==1||flag_FP==1||flag_F==1)
	begin
       char[0]<=256'h0000000000003FFC18021800181018101FF018101800180018007E0000000000; //F

	end
	else if(flag_0==1)
	begin
       char[0]<=0; 
	end
	end
	
always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[1]<=0;
		end
	else if(flag_FPG==1||flag_FPGA==1||flag_FP==1)
	begin
       char[1]<=256'h0000000000003FF0180C18061806180C1FF018001800180018007E0000000000;//P
	end
	else if(flag_F==1||flag_0==1)
	begin
       char[1]<=0;
	end
end
always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[2]<=0;
		end
	else if(flag_FPG==1||flag_FPGA==1)
	begin
       char[2]<=256'h00000000000007F818083008600060006000603C70183018181807E000000000;//G
	end
	
	else if(flag_F==1||flag_0==1||flag_FP==1)
	begin
       char[2]<=0;
	end
end
// Flag_FPGA和Flag_FPG会同时为1,所以判断时要把Flag_FPG放在前面,后续有具体解释
always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[3]<=0;
		end
	else if(flag_FPG==1||flag_F==1||flag_0==1||flag_FP==1)
	begin
       char[3]<=0;
	end
	else if(flag_FPGA==1)
	begin
        char[3]<=256'h000000000000018002C002C00460046008200FF0103010182018F83E00000000;//A
	end
end

always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[4]<=0;
		end
	else if(flag_geng==1||flag_zhou==1)
	begin
       char[4]<=256'h0020FF20242024243CA424A424A83D20242024502E50F4504488048805040602;//耿
	end
	
	else if(flag_h0==1)
	begin
       char[4]<=0;
	end
end
always @ (posedge clk1 or negedge rst_n)
begin
	if (!rst_n)
	begin
		char[5]<=0;
		end
		else if(flag_h0==1||flag_zhou==1)
	begin
       char[5]<=0;
	end
	else if(flag_geng==1)
	begin
         char[5]<=256'h00003FF8210821082FE8210821083FF8200827C82448244827C8400840288010; //周
	end
end
//在图像显示区域内,每遇到一次时钟上升沿cnt加1,使像素点和字模一一对应
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_z<= 0;
	else if(cnt_z=='d255)
	begin
        cnt_z<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK&&hcnt<=H_SYNC + H_BACK+weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_z<=cnt_z+1;
	end
end 

always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_z2<= 0;
	else if(cnt_z2=='d255)
	begin
        cnt_z2<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK+weight&&hcnt<=H_SYNC + H_BACK+2*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_z2<=cnt_z2+1;
	end
end 
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_y<= 0;
	else if(cnt_y=='d255)
	begin
        cnt_y<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_y<=cnt_y+1;
	end
end 

always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_y3<= 0;
	else if(cnt_y3=='d255)
	begin
        cnt_y3<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+2*weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+3*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_y3<=cnt_y3+1;
	end
end 
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_y4<= 0;
	else if(cnt_y4=='d255)
	begin
        cnt_y4<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+3*weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+4*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_y4<=cnt_y4+1;
	end
end 
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		cnt_y2<= 0;
	else if(cnt_y2=='d255)
	begin
        cnt_y2<=0;
	end
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+2*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1))
	begin
        cnt_y2<=cnt_y2+1;
	end
end 
//行同步信号,单位为像素 
always @ (posedge clk or negedge rst_n)
begin
	if (!rst_n)
		hcnt <= 12'd0;
	else
	begin
        if(hcnt < H_TOTAL - 1'b1)		//line over			
            hcnt <= hcnt + 1'b1;
        else
            hcnt <= 12'd0;
	end
end 

assign	lcd_hs = (hcnt <= H_SYNC - 1'b1) ? 1'b0 : 1'b1; // line over flag

//场同步信号,单位为行
always@(posedge clk or negedge rst_n)
begin
	if (!rst_n)
		vcnt <= 12'b0;
	else if(hcnt == H_TOTAL - 1'b1)	//line over
		begin
		if(vcnt == V_TOTAL - 1'b1)		//frame over
			vcnt <= 12'd0;
		else
			vcnt <= vcnt + 1'b1;
		end
end
assign	lcd_vs = (vcnt <= V_SYNC - 1'b1) ? 1'b0 : 1'b1; // frame over flag

// LED clock
assign	lcd_dclk = ~clk;

//显示
always@(posedge clk or negedge rst_n)
begin
	if (!rst_n)
		lcd_rgb <= 24'h0;
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half-5&&hcnt<=H_SYNC + H_BACK+H_DISP_half)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+V_DISP-1))	
	lcd_rgb <= 24'h0; //分割线
	else if((hcnt>=H_SYNC + H_BACK&&hcnt<=H_SYNC + H_BACK+weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&char[4][255-cnt_z])	
	lcd_rgb <=24'h0000FF; //左边汉字耿
	else if((hcnt>=H_SYNC + H_BACK+weight&&hcnt<=H_SYNC + H_BACK+2*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&char[5][255-cnt_z2])
	lcd_rgb <=24'h0000FF; //左边汉字周
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&char[0][255-cnt_y])	
	lcd_rgb <=24'h0000FF; //右边F
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+2*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&char[1][255-cnt_y2])	
	lcd_rgb <=24'h0000FF; //右边P
	else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+2*weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+3*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&(char[2][255-cnt_y3]))
	lcd_rgb <=24'h0000FF; //右边G
		else if((hcnt>=H_SYNC + H_BACK+H_DISP_half+20+3*weight&&hcnt<=H_SYNC + H_BACK+H_DISP_half+20+4*weight-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+hight-1)&&(char[3][255-cnt_y4]))	
	lcd_rgb <=24'h0000FF; //右边A
	else if((hcnt>=H_SYNC + H_BACK&&hcnt<=H_SYNC + H_BACK+H_DISP-1)&&(vcnt>=V_SYNC + V_BACK&&vcnt<=V_SYNC + V_BACK+V_DISP-1))	//line over
	lcd_rgb <=24'hFFFFFF; //背景
	else lcd_rgb <= 24'h0;
end
endmodule

注:Flag_FPGA和Flag_FPG有一点时间会同时为1,所以当要删除A时,需要把Flag_FPG的判断放在前面。在这里插入图片描述
按键消抖模块:
当第一次检测到key=0持续5ms时,产生标志位。

module key_debounce(
	input	wire 			clk,
	input	wire 			rst_n,
	input	wire 			key,
	input	wire 			key2,
	output	wire 	[3:0]	led,
	output	reg 			key_flag,
	output	reg 			key2_flag
	);
parameter 	CNT_END = 249999;
reg 	[17:0]	cnt;
reg 			cnt_flag;
reg 	[3:0]	shift_led = 4'b0001;
reg 	[17:0]	cnt2;
reg 			cnt2_flag;
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt <= 'd0;
	end
	else if (key== 1'b0) begin
		cnt <= cnt + 1'b1;
	end
	else begin
		cnt <= 'd0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt_flag <= 1'b0;
	end
	else if (key == 1'b1) begin
		cnt_flag <= 1'b0;
	end
	else if (cnt == CNT_END) begin
		cnt_flag <= 1'b1;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		key_flag <= 1'b0;
	end
	else if (cnt_flag == 1'b0 && cnt == CNT_END) begin
		key_flag <= 1'b1;
	end
	else begin
		key_flag <= 1'b0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt2 <= 'd0;
	end
	else if (key2== 1'b0) begin
		cnt2 <= cnt2 + 1'b1;
	end
	else begin
		cnt2 <= 'd0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		cnt2_flag <= 1'b0;
	end
	else if (key2 == 1'b1) begin
		cnt2_flag <= 1'b0;
	end
	else if (cnt2 == CNT_END) begin
		cnt2_flag <= 1'b1;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		key2_flag <= 1'b0;
	end
	else if (cnt2_flag == 1'b0 && cnt2 == CNT_END) begin
		key2_flag <= 1'b1;
	end
	else begin
		key2_flag <= 1'b0;
	end
end
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		shift_led <= 4'b0001;
	end
	else if (key_flag == 1'b1) begin
		shift_led <= {shift_led[2:0],shift_led[3]};
	end
end
assign  led = shift_led;
endmodule 

下面是上板的实际效果:
在这里插入图片描述
删除实际效果:(按键各按了一下)
在这里插入图片描述
注:本任务所有控制信号产生部分使用50Mhz时钟,vga显示以及控制字模和像素点一一映射部分(cnt_y等)使用vga时钟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值