The game Lemmings involves critters with fairly simple brains. So simple that we are going to model it using a finite state machine.
In the Lemmings’ 2D world, Lemmings can be in one of two states: walking left or walking right. It will switch directions if it hits an obstacle. In particular, if a Lemming is bumped on the left, it will walk right. If it’s bumped on the right, it will walk left. If it’s bumped on both sides at the same time, it will still switch directions.
Implement a Moore state machine with two states, two inputs, and one output that models this behaviour.
Lemmings 游戏涉及大脑相当简单的小动物。如此简单,我们将使用有限状态机对其进行建模。
在旅鼠的 2D 世界中,旅鼠可以处于以下两种状态之一:向左行走或向右行走。如果遇到障碍物,它会切换方向。特别是,如果 Lemming 撞到左边,它会向右走。如果它撞到右边,它会向左走。如果它同时在两侧碰撞,它仍然会切换方向。
实现一个具有两个状态、两个输入和一个输出的摩尔状态机来模拟这种行为。
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
output walk_left,
output walk_right); //
parameter LEFT=0, RIGHT=1;
reg state, next_state;
always @(posedge clk, posedge areset) begin
if (areset ==1 ) begin
state <=LEFT;
end
else
state<=next_state;
end
always @(*) begin
if (areset ==1 ) begin
next_state = LEFT;
end
else case (state)
LEFT : if (bump_left==1 )
next_state = RIGHT;
else
next_state=LEFT;
RIGHT : if (bump_right==1 )
next_state = LEFT;
else
next_state=RIGHT;
default : next_state=LEFT;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset==1) begin
walk_left <= 1 ;
walk_right <= 0 ;
end
else case (next_state)
LEFT:
begin
walk_left <= 1 ;
walk_right <= 0 ;
end
RIGHT:begin
walk_right <= 1 ;
walk_left <= 0;
end
endcase
end
endmodule
In addition to walking left and right, Lemmings will fall (and presumably go “aaah!”) if the ground disappears underneath them.
In addition to walking left and right and changing direction when bumped, when ground=0, the Lemming will fall and say “aaah!”. When the ground reappears (ground=1), the Lemming will resume walking in the same direction as before the fall. Being bumped while falling does not affect the walking direction, and being bumped in the same cycle as ground disappears (but not yet falling), or when the ground reappears while still falling, also does not affect the walking direction.
Build a finite state machine that models this behaviour.
除了左右行走之外,如果地面消失在旅鼠脚下,旅鼠还会摔倒(并且可能会“啊啊!”)。
除了左右行走和碰撞时改变方向,当ground=0时,旅鼠会摔倒并说“啊啊!”。当地面重新出现时(地面=1),旅鼠将继续沿与坠落前相同的方向行走。跌倒时被撞不影响行走方向,与地面消失(但尚未跌倒)同一个周期被撞,或仍在跌倒时再次出现地面时,也不影响行走方向。
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'b00, RIGHT=2'b01,FALL_L=2'b10,FALL_R=2'b11;
reg [1:0]state;
reg [1:0] next_state;
always @(posedge clk, posedge areset) begin
if (areset ==1 ) begin
state <=LEFT;
end
else
state<=next_state;
end
always @(*) begin
if (areset ==1 ) begin
next_state = LEFT;
end
else case (state)
LEFT : if (ground==0 )
next_state = FALL_L;
else begin
if (bump_left==1)
next_state=RIGHT;
else
next_state=LEFT;
end
RIGHT : if (ground==0 )
next_state = FALL_R;
else begin
if (bump_right==1)
next_state=LEFT;
else
next_state=RIGHT;
end
FALL_L:if (ground==1 )
next_state = LEFT;
else
next_state=FALL_L;
FALL_R:if (ground==1 )
next_state = RIGHT;
else
next_state=FALL_R;
default : next_state=LEFT;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset==1) begin
walk_left <= 1 ;
walk_right <= 0 ;
aaah<=0;
end
else case (next_state)
LEFT:
begin
walk_left <= 1 ;
walk_right <= 0 ;
aaah<=0;
end
RIGHT:begin
walk_right <= 1 ;
walk_left <= 0;
aaah<=0;
end
FALL_L: begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=1;
end
FALL_R:begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=1;
end
endcase
end
endmodule
In addition to walking and falling, Lemmings can sometimes be told to do useful things, like dig (it starts digging when dig=1). A Lemming can dig if it is currently walking on ground (ground=1 and not falling), and will continue digging until it reaches the other side (ground=0). At that point, since there is no ground, it will fall (aaah!), then continue walking in its original direction once it hits ground again. As with falling, being bumped while digging has no effect, and being told to dig when falling or when there is no ground is ignored.
(In other words, a walking Lemming can fall, dig, or switch directions. If more than one of these conditions are satisfied, fall has higher precedence than dig, which has higher precedence than switching directions.)
除了走路和摔倒,旅鼠有时会被告知做一些有用的事情,比如挖掘(当 dig=1 时它开始挖掘)。如果旅鼠当前在地面上行走(地面=1 并且没有下落),它可以挖掘,并且会继续挖掘直到它到达另一边(地面=0)。到那时,由于没有地面,它会掉下来(啊啊!),然后一旦再次撞到地面,就继续沿原来的方向行走。与坠落一样,挖掘时被撞到没有效果,并且在坠落或没有地面时被告知要挖掘被忽略。
(换句话说,行走的旅鼠可以跌倒、挖掘或切换方向。如果满足这些条件中的一个以上,则跌倒的优先级高于 dig,而 dig 的优先级高于切换方向。)
module top_module(
input clk,
input areset, // Freshly brainwashed Lemmings walk left.
input bump_left,
input bump_right,
input ground,
input dig,
output walk_left,
output walk_right,
output aaah,
output digging );
parameter LEFT=3'b000, RIGHT=3'b001,FALL_L=3'b010,FALL_R=3'b011, DIG_L=3'b100,DIG_R=3'b101;
reg [2:0]state;
reg [2:0] next_state;
always @(posedge clk, posedge areset) begin
if (areset ==1 ) begin
state <=LEFT;
end
else
state<=next_state;
end
always @(*) begin
if (areset ==1 ) begin
next_state = LEFT;
end
else case (state)
LEFT : if (ground==0 )
next_state = FALL_L;
else begin
if (dig==1)
next_state=DIG_L;
else begin
if (bump_left==1)
next_state=RIGHT;
else
next_state=LEFT;
end
end
RIGHT : if (ground==0 )
next_state = FALL_R;
else begin
if (dig==1)
next_state=DIG_R;
else begin
if (bump_right==1)
next_state=LEFT;
else
next_state=RIGHT;
end
end
FALL_L:if (ground==1 )
next_state = LEFT;
else
next_state=FALL_L;
FALL_R:if (ground==1 )
next_state = RIGHT;
else
next_state=FALL_R;
DIG_L:if (ground==0)
next_state=FALL_L;
else begin
if (dig==1)
next_state=DIG_L;
else
next_state=DIG_L;
end
DIG_R:if (ground==0)
next_state=FALL_R;
else begin
if (dig==1)
next_state=DIG_R;
else
next_state=DIG_R;
end
default : next_state=LEFT;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset==1) begin
walk_left <= 1 ;
walk_right <= 0 ;
aaah<=0;
digging<=0;
end
else case (next_state)
LEFT:
begin
walk_left <= 1 ;
walk_right <= 0 ;
aaah<=0;
digging<=0;
end
RIGHT:begin
walk_right <= 1 ;
walk_left <= 0;
aaah<=0;
digging<=0;
end
FALL_L: begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=1;
digging<=0;
end
FALL_R:begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=1;
digging<=0;
end
DIG_L:begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=0;
digging<=1;
end
DIG_R:begin
walk_left <= 0 ;
walk_right <= 0 ;
aaah<=0;
digging<=1;
end
endcase
end
endmodule