资讯详情

基于FPGA的乒乓球游戏机和排球游戏机的设计

游戏规则:

用8个发光二极管排成一条直线,两边代表双方的位置。其中一个亮光二极管指示球的当前位置。

点依次发光二极管从上到下当点亮二极管运动到最后一个,参赛者按下按钮开关位于自己一侧,若击中使球向相反的方向移动,如果没有击中,对方必须1分,一方得分时,蜂鸣器鸣叫。

甲双方用两位数码管计分数码管显示了胜利统计 ,每计满11分为一局,并统计双方的胜局数。

甲乙方各设置发光二极管,表示有发球权5发球权自动交换。

功能模块设计

分频模块

//分频模块 module  divide(clk,rst_n,clkout ); input clk,rst_n; output clkout;   //parameter是verilog里常数语句  parameter WIDTH = 32;             //计数器的位数,计数的最大值是 2**WIDTH-1  parameter N = 1000000;             ///分频系数,请确保 N < 2**WIDTH-1.否则计数会溢出    reg  [WIDTH-1:0] cnt_p,cnt_n;     //cnt_p上升沿触发时的计数器,cnt_n为下降沿触发时的计数器  reg   clk_p,clk_n;     //clk_p上升沿触发时分频时钟,clk_n下降沿触发时分频时钟    //上升沿触发时计数器的控制  always @ (posedge clk or negedge rst_n )         //posedge和negedge是verilog表示信号上升和下降                                                          //当clk上升或上升rst_n变低时执行一次always里的语句   begin    if(!rst_n)     cnt_p<=0;    else if (cnt_p==(N-1))     cnt_p<=0;    else cnt_p<=cnt_p 1;             ///计数器一直在计数,当计数到达时N-1时清零,这是一个模N计数器   end            ///上升沿触发的分频时钟输出,如果N是奇数,时钟占空比不是50%;如果N是偶数,时钟占空比为50%          always @ (posedge clk or negedge rst_n)   begin    if(!rst_n)     clk_p<=0;    else if (cnt_p<(N>>1))          //N>>一是右移一位,除以2相当于去除余数     clk_p<=0;    else      clk_p<=1;               ///分频时钟的正周期比负周期多一个clk时钟   end           ///下降沿触发时计数器的控制           always @ (negedge clk or negedge rst_n)   begin    if(!rst_n)     cnt_n<=0;    else if (cnt_n==(N-1))     cnt_n<=0;    else cnt_n<=cnt_n 1;   end           //输出沿触发的分频时钟,和clk_p相差半小时钟  always @ (negedge clk)   begin    if(!rst_n)     clk_n<=0;    else if (cnt_n<(N>>1))       clk_n<=0;    else      clk_n<=1;                ///分频时钟的正周期比负周期多一个clk时钟   end           assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p;      //条件判断表达式                                                                     //当N=1时,直接输出clk                                                                     //当N为偶数,即N的最低位为0,N(0)=0,输出clk_p                                                                     //当N为奇数,即N的最低位为1,N(0)=1,输出clk_p&clk_n。正周期多,所以是相和  endmodule 

发球接球和评分模块

always @(posedge clk12hz  or negedge rst )   begin                if(!rst)        begin        win_a<=4'b0;        win_b<=4'b0;        led8s<=9'b000000000;        state<=s0;        led8s2<=2'b01;        led8s3<=2'b00;        end   else       begin     case(state)    s7: begin     if(!k_a)      state<=s1; ///甲发球;     else if(!k_b)      state<=s四、/乙发球;     else if(speaker)      speaker<=1'b0;     else      speaker<=1'b0;     end    s0: begin      led8s<=9'b000000000;       score_a<=0;      score_b<=0;      led8s2<=2'b01;//给甲乙双方分数复位;        if(!k_a)       begin        speaker<=1'b0;//因为按钮k_a蜂鸣器鸣叫是为了保持高电位‘1’,可以放手;        state<=s7;       end      else if(!k_b)        begin         speaker<=1'b0;         state<=s7;              end         else       state<=s0;          end    s1: begin       if(led8s==9'b000000000)        led8s<=9'b一万万;//点亮的灯出现在最右边,即甲方发球;       state<=s2;      if(speaker)       speaker<=1'b0;///关闭刚刚鸣叫的蜂鸣器;     end    s2: begin      f(cnt1>=N1)
				 begin
					cnt1<=0;
					if(led8s==9'b000000010)
						begin						
							led8s <= {led8s[0],led8s[8:1]};
							state<=s3;//进入判断乙方接球的状态;
						end
					else
						begin
							led8s <= {led8s[0],led8s[8:1]};
							state<=s2;
						end
				 end
			  else
					cnt1<=cnt1+1;

				 end
			s3: begin
					if(!k_b)
						begin
							state<=s4;//乙方接球成功,并进入乙方发球的s4状态;
							led8s<=9'b000000000;
						end
					else
						begin
							score_a<=score_a+1'b1;
		
							speaker<=1'b1;
							led8s3<=2'b10;
							state<=s8;//乙方接球不成功,则甲方加一分,并进入甲方发球的s7状态,蜂鸣器鸣叫;
						end		
				end
			s4: begin
					if(led8s==9'b000000000)
							led8s<=9'b000000001;//点亮的灯出现在最左边,即乙方发球;
					state<=s5;
					if(speaker)
						speaker<=1'b0;//将刚才鸣叫的蜂鸣器关闭;
				end
			s5: begin
				if(cnt1>=N1)
				    begin
						cnt1<=0;
							if(led8s==9'b010000000)
						begin
							led8s <= {led8s[7:0],led8s[8]};
							state<=s6;//进入判断甲方接球的状态;
						end
					else
						begin
							led8s <= {led8s[7:0],led8s[8]};
							state<=s5;
					   end
					  end
				 else
				  cnt1<=cnt1+1;

							
						end
				
			s6: begin
					if(!k_a)
						begin
							state<=s1;//甲方接球成功,并进入甲方发球的s7状态;
							led8s<=9'b000000000;
						end
					else
						begin
							score_b<=score_b+1'b1;

					speaker<=1'b1;
							led8s3<=2'b01;
							state<=s8;//甲方接球不成功,则乙方加一分,并进入乙方发球的s7状态,蜂鸣器鸣叫;
						end
					end	
			

胜局统计和发球权判决模块

 

s8:begin
	      led8s<=9'b000000000;
			fp<=score_a+score_b;
				
      	 if(score_a==4'b1011)
			begin
				score_a<=0;
				score_b<=0;//如果任一方得11分,一局结束,计分清零;
		    win_a<=win_a+1'b1;
		       state<=s7;
			end
		else	if(score_b==4'b1011)
			begin
				score_a<=0;
				score_b<=0;//如果任一方得11分,一局结束,计分清零;
		    win_b<=win_b+1'b1;
	        state<=s7;		 
			end
		else	
			if(fp==4||fp==9||fp==14||fp==19)
			led8s2<=~led8s2;


          state<=s7;	
			end
	       
			default: 
			begin
				win_a<=4'b0;
				win_b<=4'b0;
				state<=s0;
			end	
		endcase
		end

分数显示模块

//----------甲乙双方的分数各用2个数码管显示-----------------------------------------------------------------
	
	end

				
		always @ (posedge clk or negedge rst)
		begin
		       if(!rst)
				   begin
		            i1<=0;
		         end
					
					else 
					   begin
				   if(i1==3'b111)
				   i1<=0;
					
				 i1<=i1+3'b001 ;
		          end
		end
		
		
always @ (posedge clk or negedge rst)		
begin
	if(!rst)
	begin
		seg1<=4'b0;
		seg2<=4'b0; 
	end
	else 
	begin
	  case(i1)
	  3'b000:
		begin
			  seg1<=4'b1011;
			  seg2<=4'b1111;
			  j1<=score_b%(4'b1010);
			
		 end		  
		  
		3'b001:
	    begin
		     seg1<=4'b0111;
			  seg2<=4'b1111;
			  j1<=score_b/(4'b1010);
		   
	    end	
	  

	
      3'b011:
	     begin
		     seg1<=4'b1110;
			  seg2<=4'b1111;
			  j1<=win_b%(4'b1010);
		   
	     end		
		
       3'b100:
	     begin
				seg1<=4'b1111;
				seg2<=4'b1110;
			   j1<=score_a%(4'b1010);
		   
	     end	
		
       3'b101:
	     begin
				seg1<=4'b1111;
				seg2<=4'b1101;
				j1<=score_a/(4'b1010);
		   
	     end		
		 

		  
	   3'b111:
	     begin
				seg1<=4'b1111;
				seg2<=4'b0111;
				j1<=win_a%(4'b1010);
			  
		   
	     end	
		
       default:;

			  
	   endcase
		end
		end

数码管显示模块

always @ (j1)
   begin
         
		   case(j1)
              8'b0000: begin
			        
							led7s1<=7'b0111111;//数码管显示0分;					
						 end
			8'b0001: begin
			                
							led7s1<=7'b0000110;//数码管显示1分;					
						 end
			8'b0010: begin
			                 
							led7s1<=7'b1011011;//数码管显示2分;					
						 end
			8'b0011: begin       
							led7s1<=7'b1001111;//数码管显示3分;			
						 end
			8'b0100: begin
							led7s1<=7'b1100110;//数码管显示4分;			
						 end
			8'b0101: begin
								led7s1<=7'b1101101;//数码管显示5分;			
						 end
			8'b0110: begin               
							led7s1<=7'b1111101;//数码管显示6分;			
						 end
			8'b0111: begin        	
							led7s1<=7'b0000111;//数码管显示7分;			
						 end
			8'b1000: begin      
							led7s1<=7'b1111111;//数码管显示8分;			
						 end
			8'b1001: begin                  
							led7s1<=7'b1101111;//数码管显示9分;			
						 end
			default: begin		         
							led7s1<=7'b0111111;//数码管显示0分;			
						 end			
            endcase
    end		
endmodule	


 

标签: 电位器上b10k

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台