名称:基于FPGA的乒乓球比赛游戏机设计Verilog代码ISE仿真
软件:ISE
语言:Verilog
代码功能:
乒乓球比赛游戏机。
功能要求:
1、设计一个由甲、乙双方参赛,有裁判的3人乒乓球游戏机。
2、用多个LED排成一条直线,以中点为界,两边各代表参赛双方的位置,其中一只点亮的LED指示球的当前位置,点亮的LED依此从左到右,或从右到左,其移动的速度应能调节;甲乙双方每隔5次自动交换发球权,拥有发球权的一方发球才有效。
3、当“球”(点亮的那LED)运动到某方的最后一位时,参赛者应能果断地按下位于自己一方的按钮开关,即表示启动球拍击球。若击中,则球向相反方向移动;若未击中,则对方得1分;一方得分时,电路自动响铃,这期间发球无效等铃声停止后方能继续比赛,设置自动记分电路,甲、乙双方音进行记分显示。每计满11分为1局。
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
1. 工程文件
2. 程序文件
3. 程序编译
4. RTL图
5. Testbench(仿真文件)
6. 仿真图
整体仿真图
甲发球并得分,甲发球权,乙发球无效
speed_ctrl控制稍球的速度
乙发球,并得分,乙发球权,甲发球无效
乙先得11分,win_led亮
部分代码展示:
`timescale?1ns?/?1ps //游戏控制模块 module?game_ctrl( ????input?clk_in, ????input?reset_p,//复位,裁判 ????input?button_posedge_1,//甲,按键1 ????input?button_posedge_2,//乙,按键2 ?input?shift_en,? ????output?[7:0]?led,//8个led ?output?reg?win_led,//一局结束指示 ?output?reg?beep,//高电平响 ????output?[7:0]?score_1,//分数1 ????output?[7:0]?score_2//分数2 ????); reg?[7:0]?led_buf=8'd0; //定义状态 parameter?s_idle=4'd0; parameter?s_start_1=4'd1; parameter?s_start_2=4'd2; parameter?s_run_L=4'd3; parameter?s_run_R=4'd4; parameter?s_win_1=4'd5; parameter?s_win_2=4'd6; parameter?s_end=4'd7; reg?[3:0]?state=4'd0; reg?[3:0]?start_ball=4'd0;//发球计数,每人5次,0~4甲,5~9乙。 always@(posedge?clk_in)//发球计数 if(start_ball<5)//发球计数,每人5次,0~4甲 if(button_posedge_1==1) start_ball<=start_ball+1; else ; else//发球计数,每人5次,5~9乙。 if(button_posedge_2==1) start_ball<=start_ball+1; else ; //状态机设计 always@(posedge?clk_in) if(reset_p==1) ????state<=s_idle; else ????case(state) ???????s_idle:begin//初始状态 ????????????led_buf<=8'd0; ????????????if(start_ball<5?&&?button_posedge_1==1)//1号发球 ????????????????state<=s_start_1; ????????????else?if(start_ball>4?&&?button_posedge_2==1)//2号发球 ????????????????state<=s_start_2; ????????????else ????????????????state<=s_idle; ????????????end ??????s_start_1:begin//1号发球起始位置 ????????????state<=s_run_R; ????????????led_buf<=8'b10000000; ????????????end ??????s_start_2:begin//2号发球起始位置 ????????????state<=s_run_L; ????????????led_buf<=8'b00000001; ????????????end?? ??????s_run_R:begin//球右移 ????????????if(shift_en) ???????????????led_buf<=led_buf>>1;//球右移 ????????????else ???????????????led_buf<=led_buf;?? ?????? ????????????if(button_posedge_2==1) ????????????????if(led_buf==8'b00000001)//判断对方是否正确位置击球?????????? ????????????????????state<=s_run_L;//改变方向 ????????????????else ????????????????????state<=s_win_1;//否则得分 ????????????else?if(led_buf==8'b00000000)//对方未在正确位置击球 ????????????????????state<=s_win_1; ????????????????else ????????????????????state<=s_run_R; ????????????end ??????s_run_L:?begin//球左移 ????????????if(shift_en) ????????????????led_buf<=led_buf<<1;//球左移 ????????????else ????????????????led_buf<=led_buf;? ???????????????? ????????????if(button_posedge_1==1) ????????????????if(led_buf==8'b10000000)//判断对方是否正确位置击球??????????? ????????????????????state<=s_run_R;//改变方向 ????????????????else ????????????????????state<=s_win_2;//否则得分 ????????????else?if(led_buf==8'b00000000)//对方未在正确位置击球 ????????????????????state<=s_win_2; ????????????????else ????????????????????state<=s_run_L;???????? ?????????????end????????? ????????s_win_1: ?if(beep_cnt>=32'd499)//响铃程持续500时钟 state<=s_idle;//返回初始状态 ?else state<=s_win_1; ????????s_win_2: ?if(beep_cnt>=32'd499)//响铃程持续500时钟 state<=s_idle;//返回初始状态 ?else state<=s_win_2; ????????default:; ???endcase //计分 reg?[7:0]?score_1_buf=8'd0; reg?[7:0]?score_2_buf=8'd0; always@(posedge?clk_in) ????if(reset_p==1) ????????score_1_buf<=8'd0; ????else ??if(state==s_win_1?&&?beep_cnt==32'd0) score_1_buf<=score_1_buf+8'd1;//加一分 always@(posedge?clk_in) ????if(reset_p==1) ????????score_2_buf<=8'd0; ????else ????????if(state==s_win_2?&&?beep_cnt==32'd0) ????????????score_2_buf<=score_2_buf+8'd1;//加一分 //任何一方先记满11分获胜 reg?beep_en=0; always@(posedge?clk_in) ????if(reset_p==1)begin ?win_led<=0; ?end ?else ?if(score_1_buf>=8'd11?||?score_2_buf>=8'd11)begin win_led<=1;//任何一方先记满11分获胜 end ?else?begin win_led<=0; end //得分自动响铃 reg?[31:0]?beep_cnt=32'd0; always@(posedge?clk_in) if(reset_p==1) beep_cnt<=32'd0; else if(state==s_win_1?||?state==s_win_2) beep_cnt<=beep_cnt+32'd1; else beep_cnt<=32'd0; always@(posedge?clk_in) if(reset_p==1) beep<=30; else if(state==s_win_1?||?state==s_win_2) beep<=1;//得分自动响铃 else beep<=0; assign?score_1=score_1_buf; assign?score_2=score_2_buf; assign?led=led_buf?|?8'b00011000;//中间2个作为中网 endmodule
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=798
290