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]