基于FPGA和Arduino的小游戏设计

该设计结合FPGA和Arduino,通过Verilog HDL编程实现了一个包含6个房间和1把剑的冒险游戏。FPGA负责游戏逻辑,Arduino处理LCD12864屏幕显示。游戏中,玩家需在9宫格迷宫中找到隐藏的剑,才能战胜龙。设计包括独立按键模块、时钟随机数模块、Maze和Room模块。通过功能仿真和测试,展示了游戏流程和结局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实物图

在这里插入图片描述
在这里插入图片描述

目 录

一、 总体设计方案…1
1.1 总体功能介绍…1
1.2 设计原理…1
1.3 VerilogHDL程序代码设计及功能介绍…5
1.4 总体电路图…6
二、功能仿真及分析…7
三、功能测试及分析…8
四、结论…15
4.1 系统特点及存在的问题…15
4.2 学习体会…15
五、附件(代码)…16

摘 要

关键词:FPGA, 时钟分频,异步时序
本设计基于FPGA(ALTERA cyloneII EP4CE6F17C8N)和Arduino(Mega2560)两种控制器,FPGA实现功能,Arduino实现屏幕显示。
定义时钟模块,为room模块和maze模块提供clk时钟。提供随机数。
定义room模块,实现重置,时钟,方向,和判断是否拿到剑,s[n]表示到达哪个房间,s3表示进入maze模块。用case语句实现走动和位置的记录,最终通过结合随机数和是否拿到sword来判断能否打败龙。
定义maze模块,制作了一个八个房间的迷宫,剑藏在随机数所确定的房间里,如果走到的房间恰好为随机数表示的房间,那么v=1,表明拿到了剑。

一、总体设计方案

1.1 总体功能描述
有6个房间和1把斩首剑,以及一个包含9个房间的迷宫(剑在迷宫内)。开始于一个嘈杂的洞穴(the Cave of Cacophony)。要想获得胜利,必须要先通过曲折的隧道(the Twisty Tunnel)和湍急的河流(the Rapid River);然后你需要进入迷宫寻找随机放置在一个房间的斩首剑(the Vorpal Sword)。这把剑将保护你通过后面危机四伏的龙穴(the Dragon Den),安全地到达胜利穹顶(the Victory Vault)赢得胜利。如果你进入龙穴而没有斩首剑,你会被凶残的暴龙撕裂分食,尸骨被扔进阴森恐怖的墓地(the Grievous Graveyard)最终输掉游戏。而如果你有斩首剑,还要根据随机数来判定你是否能取得胜利。
新功能:
1、设有九宫格式迷宫,而宝剑藏于其中,需要通过寻找来获得宝剑,增加了游戏的趣味性。
2、采用液晶屏显示,显示实时位置,并且会有如“YOU WIN”等游戏输赢结果的提示和暴龙凶恶的画面,增加游戏的可读性和趣味性。

1.2 设计原理
(1)整体示意图(游戏地图)
在这里插入图片描述
(2)子功能模块:
①独立按键模块:
在这里插入图片描述
②Maze模块:
在这里插入图片描述
3、Room模块:
在这里插入图片描述
逻辑抽象
在这里插入图片描述
(4)状态转换图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 Verilog HDL程序代码设计及功能介绍

1、独立按键模块:
(1)功能:四个按健各代表“N”“S”“W”“E”中的一个方向,实现“东”“西”“南”“北”的位置移动。
(2)设计过程:通过按键实现输入和状态转化,设计按键在电路板的四个方向,操控更加方便

2、clock_random模块:
(1)功能:①产生了两个随机数,一个是0/1,判定拿到斩首剑与暴龙战斗是否能胜利。1代表胜利,0代表失败。一个是000-111,产生斩首剑存放的房间号码。
②输出7Hz的主时钟信号,避免按一次独立按键检测到多个信号。
(2)设计过程:通过时钟产生随机数,通过三个时钟类似计数器产生000-111的信号,时间相等,因此概率也相等,在需要判定的那一刻取数,便实现了随机的效果。主时钟信号是多次调整的结果,频率太低容易检测不到,太高容易检测到多次。

3、单片机Arduino的LCD12864显示程序:
(1)功能:显示实时位置,并且会有如“YOU WIN”等游戏输赢结果的提示和暴龙凶恶的画面。
(2)设计过程:因用LED难以辨别状态,因此使用arduino的mega2560实现显示功能,通信方式为并行,通过I/O口检测高低电平显示不同的图像文字。
4、maze模块:
(1)功能:有9个房间,其中有一个房间藏着斩首剑,需要游戏者去寻找。
(2)设计过程:这是拓展部分,宝剑随机藏于0-7号房间,由东南西北四个按键控制,另外实验改进加入了一个类似锁存器的功能在模块中,以便于在进入房间一刻把随机数锁定。Maze模块属于状态3,与主模块room之间用sword_room和return_S2连接
5、Room模块:
(1)功能:有 6个房间,需要游戏者通过来可能到达迷宫寻找斩首剑以及前往龙穴战斗。
(2)设计过程:按照游戏要求设计,共7个状态,由东南西北四个按键控制。为避免进入S3后按键输入出现混乱,使用了if语句,在进入S3后room模块主功能停止作用。

1.4总体电路图

在这里插入图片描述

二、功能仿真及分析

在这里插入图片描述
在这里插入图片描述
分析:
向东:到达s1向南:到达s2
向西:到达maze,s3=1
向北:到达room0,v=0未拿到剑
向西:到达room2,v=0未拿到剑
向西:到达room5,v=0未拿到剑
向南:到达room6,v=0未拿到剑
向南:到达room7,v=0未拿到剑
向东:到达room4,v=0未拿到剑
向东:到达room1,v=0未拿到剑
向北:到达maze起点,v=0未拿到剑
向东:到达s2
向东:到达龙穴,没有剑,die=1战败死亡
reset置零,回到起点。

三、功能测试及分析

1、引脚分配
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2、测试照片
①初始界面:显示嘈杂的洞穴(0号位置),曲折的隧道(1号位置)湍急的河流(2号位置),以及暴龙形象,呼应冒险游戏的主题,渲染紧张的游戏氛围。
在这里插入图片描述
②显示初始位置:嘈杂的洞穴(0号位置)
在这里插入图片描述
③经过曲折的隧道(1号位置)湍急的河流(2号位置)到达迷宫入口(entrance),即迷宫里的初始位置(8号房间)
在这里插入图片描述
④到达“?”房间(8号房间)后,显示迷宫地图。斩首剑藏于其中一个房间。
在这里插入图片描述
⑤去不同房间寻找宝剑,当前位于迷宫的3号房间
在这里插入图片描述
⑥获得斩首剑,即将返回前往龙穴
在这里插入图片描述
⑦返回到湍急的河流,下一个地点即为龙穴
在这里插入图片描述
⑧拿到斩首剑,却因为暴龙状态极佳,而无法与之匹敌,最终死亡(“you die”)
在这里插入图片描述
⑨游戏失败的画面
在这里插入图片描述
⑩游戏者再接再厉,最终拿到斩首剑赢得胜利
在这里插入图片描述
⑪游戏胜利的欢乐画面
在这里插入图片描述

四、结论

4.1系统特点及存在的问题

系统特点
模块之间接口完美,逻辑清晰。
利用同步时序电路,明确状态的变化,可以清楚的观察游戏者所处的位置。

存在的问题

迷宫部分实现了最基本的走动和随机数功能,还可以拓展其丰富性,另外,打龙的时候用随机数的概率来获得胜利比较单调,可以再设计一个能为玩家所控制的打龙模块。迷宫部分实现了最基本的走动和随机数功能,还可以拓展其丰富性,另外,打龙的时候用随机数的概率来获得胜利比较单调,可以再设计一个能为玩家所控制的打龙模块。

4.2学习体会
学到了各个模块之间如何实现接口的信息反馈,认识到模块的可扩展性尤为重要。熟悉了各种语句比如if语句case语句。学会如何表示状态的转移。认识到正确的仿真对测试结果的重要性。

五、附件(代码)

FPGA部分 (Verilog HDL):

Room模块:

module room(
input clk,n,s,e,w,v,reset,return_S2,random,
output reg s0,s1,s2,s3,s4,s5,s6,win,die,sword_room
);
always@(posedge clk or negedge reset)
begin
if(reset==1'b0)
{s0,s1,s2,s3,s4,s5,s6,win,die,sword_room}<=10'b1000_0000_00;
else if(return_S2&&s3==1)
	begin
	{s0,s1,s2,s3,s4,s5,s6,sword_room}<=8'b0010_0000;
	end
else if(sword_room==0)
	begin 
	case ({s0,s1,s2,s3,s4,s5,s6})
	7'b1000_000:if(e==0) //s0
						{s0,s1,s2,s3,s4,s5,s6}<=7'b0100_000;
	7'b0100_000:begin//s1
					if(s==0)
						{s0,s1,s2,s3,s4,s5,s6}<=7'b0010_000;
					else if(w==0)
						{s0,s1,s2,s3,s4,s5,s6}<=7'b1000_000;
					end
	7'b0010_000:begin//s2
						if(n==0)
						{s0,s1,s2,s3,s4,s5,s6}<=7'b0100_000;
						else if(w==0)
						{s0,s1,s2,s3,s4,s5,s6}<=7'b0001_000;//s3
						else if(e==0)
						{s0,s1,s2,s3,s4,s5,s6}<=7'b0000_100;//s4
						end
	7'b0001_000:begin//s3
					sword_room<=1;
					end
	7'b0000_100:begin//s4
						if(v==0)
						begin
								{s0,s1,s2,s3,s4,s5,s6}<=7'b0000_001;//s6
						end
								else 
									begin
									if(random==0)
									{s0,s1,s2,s3,s4,s5,s6}<=7'b0000_010;//s5
									else
									{s0,s1,s2,s3,s4,s5,s6}<=7'b0000_001;//s6
									end
					end

	7'b0000_010:begin//s5
					win<=1;
					end
	7'b0000_001:begin//s6
					die<=1;
					end
	default:{s0,s1,s2,s3,s4,s5,s6}<=7'b1000_000;
								
endcase

end
end					
endmodule

maze模块:

module maze(
input clk,n,s,e,w,reset,sword_room,
input[2:0]random,
output reg v,
output reg return_S2,
output reg [8:0] room
);
reg[3:0]state=4'b1000;
reg flag=0;
reg [2:0]locked=3'b111;
always@(posedge clk or negedge reset)
begin
				if(reset==1'b0)
				begin
				state<=4'b1000;
				flag<=0;
				locked[2:0]<=3'b111;
				v<=0;
				return_S2<=0;
				room<=9'b100_000_000;
				end
				else if(sword_room)
						
						begin
							if(flag==0)
							begin
							locked[2:0]<=random[2:0];
							flag<=1;
							end
						case(state)
						4'b0000:begin
						room<=9'b000_000_001;//room0
							if(w==0)state<=4'b0010;//2
							else if(s==0)state<=4'b1000;//8
							else state<=4'b000;
							end
						4'b0001:begin
						room<=9'b000_000_010;//room1
							if(w==0)state<=4'b0100;
							else if(n==0)state<=4'b1000;
							else state<=4'b0001;
							end
						4'b0010:begin
						room<=9'b000_000_100;//room2
							if(s==0)state<=4'b0011;
							else if(w==0)state<=4'b0101;
							else if(e==0)state<=4'b0000;
							else state<=4'b0010;
							end
						4'b0011:begin
						room<=9'b000_001_000;//room3
							if(e==0)state<=4'b1000;
							else if(w==0)state<=4'b0110;
							else if(n==0)state<=4'b0010;
							else if(s==0)state<=4'b0100;
							else state<=4'b0011;
							end
						4'b0100:begin
						room<=9'b000_010_000;//room4
							if(e==0)state<=4'b0001;
							else if(n==0)state<=4'b0011;
							else if(w==0)state<=4'b0111;
							else state<=4'b0100;
							end
						4'b0101:
							begin
							room<=9'b000_100_000;
							if(e==0)state<=4'b0010;
							else if(s==0)state<=4'b0110;
							else state<=4'b0101;
							end
						4'b0110:begin
						room<=9'b001_000_000;
							if(e==0)state<=4'b0011;
							else if(s==0)state<=4'b0111;
							else if(n==0)state<=4'b0101;
							else state<=4'b0110;
							end
						4'b0111:begin
						room<=9'b010_000_000;
							if(e==0)state<=4'b0100;
							else if(n==0)state<=4'b0110;
							else state<=4'b0111;
							end
						4'b1000:begin
						room<=9'b100_000_000;//room8
							if(e==0)  r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值