VGA版英雄难过棍子关

module top(clk, 
           restart, 
           rst_n, 
           sw_en, 
           hsync, 
           led, 
           rgb, 
           vsync);


    input clk;
    input restart;
    input rst_n;
    input sw_en;
   output hsync;
   output [7:0] led;
   output [2:0] rgb;
   output vsync;
   
   wire [7:0] XLXN_11;
   
   led_show  XLXI_1 (.clk(clk), 
                    .rst_n(rst_n), 
                    .rx_en(XLXN_11[7:0]), 
                    .led(led[7:0]));
   vga_hero  XLXI_2 (.clk(clk), 
                    .restart(restart), 
                    .rst_n(rst_n), 
                    .sw_en(sw_en), 
                    .guan_out(XLXN_11[7:0]), 
                    .hsync(hsync), 
                    .rgb(rgb[2:0]), 
                    .vsync(vsync));
endmodule
//------------------------------------------------------
//	Title			:	VGA棍子英雄
//	Project			:	VGA_HERO	
//	Filename		:	vga_hero.v
//	Description		:	SW0复位,SW1开始,BTN1左移,BTN0右移
//					有几率开启作弊行为(留了一个BUG,读者可以改改)
//	Date			:	2015-2-14 
//	Author			:	缺Ga
//	Tool			:	ISE
//	Device			:	Xilin Spartan3E FPGA (xc3s100e-4tq144)
//	Copyright		:	江苏大学212-EDA
//------------------------------------------------------
module vga_hero(
				clk,
				rst_n,
				restart,
				hsync,
				vsync,
				sw_en,
				guan_out,
				rgb
	  );
//******************************************************
//PARAMETERS					(参数)
//******************************************************	
//------------------------------------------------------
//===同步脉冲   后沿   显示脉冲 后沿   帧长
//===
//===  128     88    800     40   1056
//===   4      23    600     1    628
//争对不同的液晶显示屏,请读者自己修改参数,否则会出现显示范围不正确
//------------------------------------------------------
//HSYNC Single(列像素)
parameter 		H_800    = 11'd800,		//	
			H_840	 = 11'd840,		// 
			H_968    = 11'd968,		//
			H_1056   = 11'd1056;		//
//VSYNC Single(行像素)
parameter		V_600    = 10'd600,		//         
			V_601	 = 10'd601, 		//
			V_605    = 10'd605,		//
			V_628    = 10'd628; 		//
//定义人和边界距离
parameter		P_DIS	 = 11'd40;
//棍子附加长度
parameter		GUN_DIS	= 11'd5;					
			
//******************************************************
//INPUTS			(输入)
//******************************************************
	input       	clk;	<span style="white-space:pre">	</span>//system clk
	input		rst_n;		//reset,low active
	input		sw_en;		//控制棍子伸长
	input		restart;	//重新开始
//******************************************************
//OUTPUTS			(输出)
//******************************************************	
	output       	hsync;
	output		vsync;
	output [2:0] 	rgb;	
	output [7:0]	guan_out;
		
//******************************************************
//LOCAL VARIABLE		(局部变量)
//******************************************************
//Register(寄存器)
	reg          	vsync;
	reg    <span style="white-space:pre">	</span> [2:0] 	rgb;	 
	reg 	 [10:0]	h_cnt;		//行坐标
	reg	 [10:0]	v_cnt;		//列坐标
	reg 		color_en;
	reg		hsync_r; 
	reg	 [10:0]	H_X;			//大圆心坐标
	reg	 [10:0]	V_Y;			//大圆心坐标
	reg	 [10:0]	x_roll;		
	reg	 [10:0]	y_roll;
	reg	 [23:0]	cnt;
	reg	 [23:0]	count;	
	reg		clk_4;		//每秒四次
	reg	 [10:0]	gun_l;
	reg	 [2:0]	clk_shake;	//小人抖动的基础时间	
	reg	 [5:0]	clk_period;	//小人抖动的周期
	reg		code;			//翻转信号
	reg				shake_en;	//确定小人可以抖	
	reg	[10:0]	x_ta;		//短距离
	reg	[10:0]	y_ta;		//长距离
	reg	[10:0]	p_ta;		//第一个塔的距离	
	reg	[7:0]	guan;
	reg		game_lose;	//游戏结束
	reg		tiao;		//跳的距离嘎嘣
	reg	[10:0]	t_guan;	//闯关结束时间
	reg		next_guan;
	
//Wire
	wire         	hsync;

//******************************************************
//MAIN CODES					(代码)
//******************************************************
//
always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0) 
		h_cnt <= 1'b0;
	else if(h_cnt < H_1056)
		h_cnt <= h_cnt + 1'b1;  
	else 	
		h_cnt <= 1'b0;  
end
//
always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
		hsync_r <= 1'b1;
	else if((h_cnt >= H_840) && (h_cnt < H_968))
		hsync_r <= 1'b0; 
	else
		hsync_r <= 1'b1; 
end
//
assign hsync = hsync_r;   

//
always @(posedge hsync_r or negedge rst_n)
begin
	if(rst_n == 1'b0)
		v_cnt <= 1'b0;
	else if(v_cnt < V_628) 
		v_cnt  <= v_cnt + 1'b1;
	else
		v_cnt <= 1'b0;
end
//
always @(posedge hsync_r or negedge rst_n)
begin 
	if(rst_n == 1'b0)
		vsync <= 1'b1;
	else if(v_cnt >= V_601 && v_cnt < V_605)
		vsync <= 1'b0;
	else 
		vsync <= 1'b1;
end
//判断输出COLOR
always @(posedge clk or negedge rst_n)
begin
	if(rst_n == 1'b0)
		color_en <= 1'b0;
	else if(h_cnt >= H_840 || v_cnt >= V_601)
		color_en <= 1'b0;
	else
		color_en <= 1'b1;
end 
//设置运动时间 
always @(posedge clk or negedge rst_n)
begin 
	if(rst_n == 1'b0)
	begin
		cnt <= 1'b0;
		clk_4 <= 1'b0;
	end else 
	if(cnt == 19'd250_000)
	begin
		cnt <= 1'b0;
		clk_4 <= ~clk_4;
	end else
		cnt <= cnt + 1'b1;
end
//记录小人不动时间超过1秒
always @(posedge code or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		clk_shake <= 1'b0;
		shake_en <= 1'b0;
	end else
	if(restart == 1'b1)
	begin
		clk_shake <= 1'b0;
		shake_en <= 1'b0;
	end else	
	begin
		if(clk_shake == 3'd8)
		begin
			clk_shake <= 1'b0;
			shake_en <= 1'b1;
		end else
			clk_shake <= clk_shake + 1'b1;
	end 
end
//
always @(posedge clk_4 or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		clk_period <= 1'b0;
		code <= 1'b0;
	end else 
	begin
		clk_period <= clk_period + 1'b1;
		if(clk_period == 6'd12)
		begin
			clk_period <= 1'b0;
			code <= ~code;
		end else	;
	end
end	
//初始化设置第一个圆心
always @(posedge clk_4 or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		V_Y <= 11'd100;	//初始月亮Y
		H_X <= 11'd540;	//初始月亮X
	end else 
	if(restart == 1'b0)
	begin
		V_Y <= 11'd100;	//初始月亮Y
		H_X <= 11'd540;	//初始月亮X
	end else ;
end

//塔的宽度
always @(posedge clk_4 or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		x_ta	<= 11'd400;
		y_ta	<= 11'd600;
		p_ta	<= 11'd200;
	end else
	if(restart == 1'b1)
		begin
			x_ta	<= 11'd400;
			y_ta	<= 11'd600;
			p_ta	<= 11'd200;			
		end else
		case(guan)
			8'd1:
					begin
						x_ta	<= 11'd400;
						y_ta	<= 11'd600;
					end 	
			8'd2:
					begin
						x_ta	<= 11'd400;
						y_ta	<= 11'd550;
					end 	
			8'd3:
					begin
						x_ta	<= 11'd450;
						y_ta	<= 11'd510;
					end 	
			8'd4:
					begin
						x_ta	<= 11'd420;
						y_ta	<= 11'd500;
					end
			8'd5:
					begin
						x_ta	<= 11'd400;
						y_ta	<= 11'd600;
					end 	
					
			default:
					if(next_guan)
					begin
						x_ta	<= x_ta + 15;
						y_ta	<= y_ta + 5;
					end 					
		endcase
end
//棍子的产生
always @(posedge clk_4 or negedge rst_n)
begin
	if(rst_n == 1'b0)
	begin
		gun_l <= 1'b0;
		x_roll <= p_ta - 11'd40;	//初始小圆X		
		y_roll <= 11'd377;	//初始小圆Y		
		game_lose <= 1'b0;		
		guan <= 1'b1;
		next_guan <= 1'b0;
	end else
	begin
		if((restart == 1'b1))
		begin
			gun_l <= 1'b0;	
			x_roll <= p_ta - 11'd40;	
			y_roll <= 11'd377;	//初始小圆Y	
			game_lose <= 1'b0;	
			guan <= 1'b1;
			game_lose <= 1'b0;
		end else
		if(game_lose == 1'b0)
		begin
			if(next_guan == 1'b1)
			begin
				gun_l <= 1'b0;	
				x_roll <= p_ta - 11'd40;	
				y_roll <= 11'd377;	//初始小圆Y	
				guan <= guan + 1'b1;
				next_guan <= 1'b0;
				t_guan <= 1'b0;					
			end else 
			if(sw_en == 1'b1)
			begin
				if(gun_l < 460)	//棍子最长
					gun_l <= gun_l + 1'b1;
				else	;
				x_roll <= p_ta - 11'd40;
			end else
			begin		
				if(((x_ta - p_ta + 2*GUN_DIS) > gun_l) || ((y_ta - p_ta + GUN_DIS) <  gun_l))
					begin
						if(x_roll == (p_ta + GUN_DIS + gun_l))
						begin
							if((y_roll < 620) && (gun_l > 1'b1))
								y_roll <= y_roll + 11'd2;		//小人掉落
							if(y_roll == 11'd620)
								game_lose <= 1'b1;	
						end
						if((x_roll < (p_ta + GUN_DIS + gun_l))&& (gun_l > 1'b1))
						begin
							x_roll <= x_roll + 1'b1;		
							if(shake_en == 1'b1)	//小人跳起来
								y_roll <= code? (tiao? 11'd365:11'd374) : (tiao? 11'd368:11'd377);
							else
								y_roll <= 11'd377;
						end	
					end else 
					begin
						if(x_roll < y_ta - 11'd40)
							x_roll <= x_roll + 1'b1;	
						else if(t_guan == 100)		//等待下一关时间
							next_guan <= 1'b1;
						else
						t_guan <= t_guan + 1'b1;								
					if(shake_en == 1'b1)	//小人跳起来
						y_roll <= code? (tiao? 11'd365:11'd374) : (tiao? 11'd368:11'd377);
					else
						y_roll <= 11'd377;
					end
				if((x_roll < (p_ta + GUN_DIS)) || (x_roll > x_ta))
					tiao <= 1'b0;
				else
					tiao <= 1'b1;
			end		
		end else	
		gun_l <= 1'b0;	
	end
end
//划分显色区域
always @(color_en or h_cnt or v_cnt )    
begin 
	if(color_en == 1'b0)
		rgb <= 1'b0;
	else 
	begin
		if(((v_cnt - V_Y)*(v_cnt - V_Y) + (h_cnt - H_X)*(h_cnt - H_X)) < 3600)	//显示月亮
			rgb <= 3'h3;	
		else if((sw_en == 1'b1) && (h_cnt > (p_ta-9)) && (h_cnt < p_ta)		//棍子粗9
					&& (v_cnt > (460 - gun_l)) && (v_cnt < 461))
			rgb <= 3'h0;	//竖棍子			
		else if((sw_en == 1'b0) && (h_cnt > (p_ta - 9)) && (h_cnt < ((p_ta - 9) + gun_l))
					&& (v_cnt > 452) && (v_cnt < 461))
			rgb <= 3'h0;	//横棍子			
		else if((h_cnt > 11'd30) && (h_cnt < p_ta) && (v_cnt > 461) && (v_cnt < 601))
			rgb <= 3'h0;		//人站的第一个塔
		else if((h_cnt > x_ta) && (h_cnt < y_ta) && (v_cnt > 461) && (v_cnt < 601))
			rgb <= 3'h0;		//塔
		else if(((v_cnt - y_roll)*(v_cnt - y_roll) + 
					(h_cnt - x_roll)*(h_cnt - x_roll)) < 225)	//显示小人头部
			rgb <= 3'h0;
		else if((h_cnt > (x_roll - 11'd30)) && (h_cnt < (x_roll + 11'd30)) 
					&& (v_cnt > (y_roll + 11'd15)) && (v_cnt < (y_roll + 11'd25)))
			rgb <= 3'h0;	//显示胳膊
		else if((h_cnt > (x_roll - 11'd15)) && (h_cnt < (x_roll + 11'd15)) 
					&& (v_cnt > (y_roll + 11'd25)) && (v_cnt < (y_roll + 11'd55)))
			rgb <= 3'h0;	//显示肚子
		else if((h_cnt > (x_roll - 11'd15)) && (h_cnt < (x_roll - 11'd3)) 
					&& (v_cnt > (y_roll + 11'd55)) && (v_cnt < (y_roll + 11'd85)))
			rgb <= 3'h0;	//显示左腿
		else if((h_cnt > (x_roll + 11'd3)) && (h_cnt < (x_roll + 11'd15)) 
					&& (v_cnt > (y_roll + 11'd55)) && (v_cnt < (y_roll + 11'd85)))
			rgb <= 3'h0;	//显示右腿
		else
			rgb <= 3'h6;
	end 
end

//
assign		guan_out = guan;
endmodule
//------------------------------------------------------
//<span style="white-space:pre">	</span>Title<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>LED显示模块
//<span style="white-space:pre">	</span>Project<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>VGA_HERO<span style="white-space:pre">		</span>
//<span style="white-space:pre">	</span>Filename<span style="white-space:pre">		</span>:<span style="white-space:pre">	</span>led.v
//<span style="white-space:pre">	</span>Description<span style="white-space:pre">		</span>:<span style="white-space:pre">	</span>LED根据关数状态显示
//<span style="white-space:pre">	</span>Date<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>2015-2-15 
//<span style="white-space:pre">	</span>Author<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>缺Ga
//<span style="white-space:pre">	</span>Tool<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>ISE
//<span style="white-space:pre">	</span>Device<span style="white-space:pre">			</span>:<span style="white-space:pre">	</span>Xilin Spartan3E FPGA (xc3s100e-4tq144)
//<span style="white-space:pre">	</span>Copyright<span style="white-space:pre">		</span>:<span style="white-space:pre">	</span>江苏大学212-EDA
//------------------------------------------------------
module led_show(
<span style="white-space:pre">				</span>clk,
<span style="white-space:pre">				</span>rst_n,
<span style="white-space:pre">				</span>rx_en,
<span style="white-space:pre">				</span>led
<span style="white-space:pre">		</span>);
<span style="white-space:pre">		</span>
//******************************************************
//PARAMETERS<span style="white-space:pre">			</span>(参数)
//******************************************************<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>parameter <span style="white-space:pre">	</span>FENPIN1 = 11'd25;<span style="white-space:pre">		</span>//根据要求,自由修改
<span style="white-space:pre">	</span>parameter <span style="white-space:pre">	</span>FENPIN2 = 16'd2000;
//******************************************************
//INPUTS<span style="white-space:pre">			</span>(输入)
//******************************************************
<span style="white-space:pre">	</span>input<span style="white-space:pre">			</span>clk;<span style="white-space:pre">			</span>//system clk
<span style="white-space:pre">	</span>input<span style="white-space:pre">			</span>rst_n;<span style="white-space:pre">		</span>//reset,low active
<span style="white-space:pre">	</span>input<span style="white-space:pre">	</span>[7:0]<span style="white-space:pre">	</span>rx_en;<span style="white-space:pre">		</span>//a关数
<span style="white-space:pre">	</span>
//******************************************************
//OUTPUTS<span style="white-space:pre">						</span>(输出)
//******************************************************<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>output<span style="white-space:pre">	</span>[7:0]<span style="white-space:pre">	</span>led;<span style="white-space:pre">		</span>
<span style="white-space:pre">		</span>
//******************************************************
//LOCAL VARIABLE<span style="white-space:pre">				</span>(局部变量)
//******************************************************
//Register(寄存器)
  reg<span style="white-space:pre">		</span>[10:0]<span style="white-space:pre">	</span>cnt_fp;       //分频计数 
  reg<span style="white-space:pre">		</span>[15:0]<span style="white-space:pre">	</span>cnt;<span style="white-space:pre">	</span>       <span style="white-space:pre">	</span>//PWM计数
  reg<span style="white-space:pre">		</span>[10:0]<span style="white-space:pre">	</span>pwm_cnt;     <span style="white-space:pre">	</span>//改变PWM的占空比
  reg<span style="white-space:pre">		</span>[7:0]<span style="white-space:pre">		</span>led_r;
  reg<span style="white-space:pre">					</span>ready_en;<span style="white-space:pre">		</span>//判断是否到最大值  
//Wire


//******************************************************
//MAIN CODES<span style="white-space:pre">					</span>(代码)
//******************************************************


//------------------------------------------------------
//呼吸灯模块<span style="white-space:pre">						</span>(密码错误时显示)
//------------------------------------------------------
//产生分频计数
always@(posedge clk or negedge rst_n)
begin
<span style="white-space:pre">	</span>if(rst_n == 1'b0) 
<span style="white-space:pre">		</span>cnt_fp<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>1'b0;
<span style="white-space:pre">	</span>else 
<span style="white-space:pre">	</span>if(cnt_fp == FENPIN1) 
<span style="white-space:pre">		</span>cnt_fp<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>1'b0;
<span style="white-space:pre">	</span>else 
<span style="white-space:pre">		</span>cnt_fp<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>cnt_fp + 1'b1;
end
//PWM                               
always@(posedge clk or negedge rst_n)
begin
<span style="white-space:pre">	</span>if(rst_n == 1'b0)
<span style="white-space:pre">		</span>cnt<span style="white-space:pre">	</span><= 1'b0;
<span style="white-space:pre">	</span>else 
<span style="white-space:pre">	</span>if((cnt_fp == FENPIN1) && (cnt == FENPIN2))
<span style="white-space:pre">		</span>cnt<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>1'b0;
<span style="white-space:pre">	</span>else  
<span style="white-space:pre">	</span>if(cnt_fp == FENPIN1)
<span style="white-space:pre">		</span>cnt<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>cnt + 1'b1;
<span style="white-space:pre">	</span>else<span style="white-space:pre">	</span>;
end
//PWM占空比变化
always@(posedge clk or negedge rst_n)
begin
<span style="white-space:pre">	</span>if(rst_n == 1'b0)
<span style="white-space:pre">	</span>begin
<span style="white-space:pre">		</span>pwm_cnt<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>1'b0;
<span style="white-space:pre">		</span>ready_en <= 1'b0;
<span style="white-space:pre">	</span>end else  
<span style="white-space:pre">		</span>if((cnt == FENPIN2) && (cnt_fp == FENPIN1))
<span style="white-space:pre">			</span>if(ready_en == 1'b0)
<span style="white-space:pre">			</span>begin
<span style="white-space:pre">				</span>pwm_cnt<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>pwm_cnt + 1'b1; 
<span style="white-space:pre">				</span>if(pwm_cnt == FENPIN2)
<span style="white-space:pre">					</span>ready_en <= 1'b1;
<span style="white-space:pre">				</span>else ;
<span style="white-space:pre">			</span>end else  <span style="white-space:pre">		</span>
<span style="white-space:pre">			</span>begin
<span style="white-space:pre">				</span>pwm_cnt<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>pwm_cnt - 1'b1;         
<span style="white-space:pre">				</span>if(pwm_cnt == 1'b0)
<span style="white-space:pre">					</span>ready_en <= 1'b0;<span style="white-space:pre">				</span>
<span style="white-space:pre">				</span>else<span style="white-space:pre">	</span>;
<span style="white-space:pre">			</span>end
end
//------------------------------------------------------
//LED显示
//------------------------------------------------------       
//控制LED状态
always@(posedge clk or negedge rst_n)
begin
<span style="white-space:pre">	</span>if(rst_n == 1'b0)
<span style="white-space:pre">		</span>led_r<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>8'b0000_0000;
<span style="white-space:pre">	</span>else 
<span style="white-space:pre">	</span>begin
<span style="white-space:pre">	</span>if(cnt > pwm_cnt)
<span style="white-space:pre">		</span>led_r<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>rx_en;
<span style="white-space:pre">	</span>else
<span style="white-space:pre">		</span>led_r<span style="white-space:pre">	</span><=<span style="white-space:pre">	</span>8'b0000_0000; 
<span style="white-space:pre">	</span>end 
end


//
<span style="white-space:pre">	</span>assign<span style="white-space:pre">	</span>led = led_r;


endmodule                                
  
 

一:项目名称[/b]
       VGA版英雄难过棍子关
[b]二:项目概述[/b]
      本设计是基于Basys2开发板的一款VGA显示小游戏,内容简单,程序也非常简单,新手可以修改其中的一部分代码来实现新的游戏。另外程序为.v文件,用ISE编辑的,下载后用其他编辑软件入UE、EditPlus、txt文本文档打开有可能看起来不美观。
[b]三:作品实物图[/b]
[attachimg]12236[/attachimg]
      
[b]四:演示视频[/b]
[url=http://v.youku.com/v_show/id_XOTA1NDI2MDM2.html]VGA版英雄难过棍子关视频地址【优酷】[/url]
[b]五:DEMO[/b]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值