|
![](http://cache.amobbs.com/bbs_upload782111/files_8/ourdev_186577.jpg)
![](http://cache.amobbs.com/bbs_upload782111/files_8/ourdev_186578.jpg)
![](http://cache.amobbs.com/bbs_upload782111/files_8/ourdev_186579.jpg)
乒乓球游戏机
一、 实验目的
1、学习较复杂状态及设计方法;
2、掌握通过采样防止开关抖动的方法
3、初步了解功能分割的方法
二、 试验说明
本试验设计一个简单的乒乓球游戏机。它可以有两个人进行游戏,游戏规则如下:
1.过早击球,对方获胜;
2.每次击球,若球飞出界外,对方获胜。
试验用8 个状态代表乒乓球的运动轨迹,两个输出信号指示获胜方,两个输入信号
代表双方的球拍,输入信号击球低有效。因为一般的开关在大约20ms 内信号不稳定,
存在所谓的“开关抖动”,会产生多个脉冲影响电路正常工作。所以含开关输入的设计
需要做防抖动处理,在本试验可以用20Hz 的时钟采样击球信号实现防抖。
设计时需要考虑乒乓球的运动规律和游戏规则的要求。乒乓球运动可分解为两个因
素:运动方向、位置。状态及中可以用八个发光二极管代表八个位置,即
1<---------􀃆 2<---------􀃆 3<---------􀃆 4<---------􀃆 5 <---------􀃆 6 <---------􀃆 7
<---------􀃆 8
根据游戏规则,在本方位置击球有效,在对方位置击球或球超出1 位置或8 位置,
则对方获胜。游戏结果有两个状态,即左方获胜和右方获胜,进入作方获胜或有方获胜
状态后,可以直接或用复位开关推出两个状态。可以将游戏结果与乒乓球位置统一成一
个状态机,共10 个状态。
游戏机的乒乓球运动速度用单位时间的移动的位置书代表,以每秒一个位置或两个
位置为宜,可以通过系统时钟控制。游戏机的乒乓球运动只能够有两个运动方向,即向
左或向右。
根据以上说明,对状态机进行编码,画出状态转移图,并用verilog 语言进行建模。
注意个状态机输入和输出信号之间的关系。
三、 试验要求
1、分别输入状态机设计文件,编译,调试通过。
2、对程序进行仿真,检查各种情况下结果是否正确。
四、 总结报告要求
1、写出个状态机的状态编码方案,状态机转移图,verilog 文件,仿真结果波形。
2、写出测试记录。
//pingpang 规则:输者发球
module pingpang(clk,rst,left_hit,right_hit,ball_state);
input clk,rst,left_hit,right_hit;
output[9:0] ball_state;
reg[9:0] ball_state;
reg[9:0] current_state;
reg[9:0] next_state;
reg direction;
parameter left = 1'b1, right = 1'b0;
parameter left_lose = 10'b1000000000,
s1 = 10'b0100000000,
s2 = 10'b0010000000,
s3 = 10'b0001000000,
s4 = 10'b0000100000,
s5 = 10'b0000010000,
s6 = 10'b0000001000,
s7 = 10'b0000000100,
s8 = 10'b0000000010,
right_lose = 10'b0000000001;
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
always @ (posedge clk or posedge rst )
if(rst)
current_state <= left_lose;
else
current_state <= next_state;
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always @ (current_state or left_hit or right_hit) //电平触发
begin
case(current_state)
left_lose:
begin
direction = right;
next_state = s1;
end
s1:
begin
if(left_hit) direction = right;
if(direction == right)
next_state = s2;
else
next_state = left_lose;
if(right_hit) next_state = right_lose;
end
s2:
begin
if(left_hit) direction = right;
if(direction == right)
next_state = s3;
else
next_state = s1;
if(right_hit) next_state = right_lose;
end
s3:
begin
if(left_hit) direction = right;
if(direction == right)
next_state = s4;
else
next_state = s2;
if(right_hit) next_state = right_lose;
end
s4:
begin
if(left_hit) direction = right;
if(direction == right)
next_state = s5;
else
next_state = s3;
if(right_hit) next_state = right_lose;
end
s5:
begin
if(right_hit) direction = left;
if(direction == right)
next_state = s6;
else
next_state = s4;
if(left_hit) next_state = left_lose;
end
s6:
begin
if(right_hit) direction = left;
if(direction == right)
next_state = s7;
else
next_state = s5;
if(left_hit) next_state = left_lose;
end
s7:
begin
if(right_hit) direction = left;
if(direction == right)
next_state = s8;
else
next_state = s6;
if(left_hit) next_state = left_lose;
end
s8:
begin
if(right_hit) direction = left;
if(direction == left)
next_state = s7;
else
next_state = right_lose;
if(left_hit) next_state = left_lose;
end
right_lose:
begin
direction = left;
next_state = s8;
end
default:
next_state = left_lose; //阻塞赋值
endcase
end
//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always @(posedge clk)
case(next_state)
left_lose:
ball_state <= left_lose;//output
s1:
ball_state <= s1;
s2:
ball_state <= s2;
s3:
ball_state <= s3;
s4:
ball_state <= s4;
s5:
ball_state <= s5;
s6:
ball_state <= s6;
s7:
ball_state <= s7;
s8:
ball_state <= s8;
right_lose:
ball_state <= right_lose;
default:
ball_state <= left_lose;
endcase
endmodule
下载到板子上有时后会出现和时序仿真一样的问题,动一动left_hit或者right_hit就好了,奇怪了 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|