相比上一题为游戏增加了地面的属性,当输入的地面信号指示为0 (地面消失)的时候,代表玩家掉落(Ahhhh状态),值得注意的一点是当玩家重新掉落到地面的时候应该按照原来的方向继续行走,并且在掉落的时候不计碰撞状态。
一开始的思路是记录掉落之前的方向,然后结束掉落状态的时候回到原来的方向上,这就相当于需要增加一个寄存器寄存住掉落之前的状态。但是仿真样例显示错误,先贴上错误的代码。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter LEFT = 2'd0;
parameter RIGHT = 2'd1;
parameter FALL = 2'd2;
reg [1:0] state,next_state;
reg [1:0] bf_state;
always @(posedge clk or posedge areset) begin
if(areset == 1'b1) begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
always @(*) begin
case(state)
LEFT: begin
if(ground == 1'b0) begin
next_state = FALL;
bf_state = LEFT;
end
else begin
if(bump_left == 1'b1) begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
end
RIGHT: begin
if(ground == 1'b0) begin
next_state = FALL;
bf_state = RIGHT;
end
else begin
if(bump_right == 1'b1) begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
end
FALL: begin
if(ground == 1'b1) begin
next_state = bf_state;
end
else begin
next_state = FALL;
end
end
default:begin
next_state = LEFT;
bf_state = LEFT;
end
endcase
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL);
endmodule
仿真输出出现错误,错误出现在掉落之后返回的状态不对
思考了一下原因应该出现在状态机的跳转部分,敏感列表使用 always @(*) ,造成输入变化过快的情况下无法,锁定掉落之前的方向。
增加状态机的状态如下图,结果正确
正确解法:使用2个状态来储存掉落状态
//正确解法
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
output walk_left,
output walk_right,
output aaah );
parameter LEFT = 2'd0;
parameter RIGHT = 2'd1;
parameter FALL_L = 2'd2;
parameter FALL_R = 2'd3;
reg [1:0] state,next_state;
always @(posedge clk or posedge areset) begin
if(areset == 1'b1) begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
always @(*) begin
case(state)
LEFT: begin
if(ground == 1'b0) begin
next_state = FALL_L;
end
else begin
if(bump_left == 1'b1) begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
end
RIGHT: begin
if(ground == 1'b0) begin
next_state = FALL_R;
end
else begin
if(bump_right == 1'b1) begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
end
FALL_L: begin
if(ground == 1'b1) begin
next_state = LEFT;
end
else begin
next_state = FALL_L;
end
end
FALL_R: begin
if(ground == 1'b1) begin
next_state = RIGHT;
end
else begin
next_state = FALL_R;
end
end
default:begin
next_state = LEFT;
end
endcase
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL_L)|(state == FALL_R);
endmodule