HDLBits刷题合集—16 Finite State Machines-2 Lemmings
HDLBits-129 Lemmings1
Problem Statement
Lemmings游戏涉及具有简单大脑的生物。 如此简单以至于我们将使用有限状态机对其进行建模。
在Lemmings的2D世界中,Lemmings可以处于以下两种状态之一:向左行走或向右行走。 如果碰到障碍物,它将切换方向。 特别是,如果Lemmings在左侧发生碰撞,它将向右行走。 如果它撞到右边,它将向左走。 如果同时在两侧碰撞,它将仍然会切换方向。
用两个状态,两个输入和一个输出对此行为进行建模,以实现Moore型状态机。
hint里给出了状态转换图,如下所示:
代码如下:
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[1:0] state, next_state;
always @(*) begin
// State transition logic
case (state)
LEFT: next_state <= bump_left ? RIGHT : LEFT;
RIGHT: next_state <= bump_right ? LEFT : RIGHT;
endcase
end
always @(posedge clk, posedge areset) begin
// State flip-flops with asynchronous reset
if (areset)
state <= LEFT;
else
state <= next_state;
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
endmodule
HDLBits-130 Lemmings2
Problem Statement
另请参阅:Lemmings1。
除了左右走动之外,如果地面在它们下面消失,它们将掉落(可能会喊“aaah!”)。
除了在碰撞时左右走动和改变方向外,当ground= 0时,旅鼠也会掉下来并说“ aaah!”。 当地面重新出现时(ground= 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 = 0, RIGHT = 1, FALL_L = 2, FALL_R = 3;
reg [2:0] state, state_next;
always @(*) begin
case (state)
LEFT : begin
if (ground)
state_next <= bump_left ? RIGHT : LEFT;
else
state_next <= FALL_L;
end
RIGHT : begin
if (ground)
state_next <= bump_right ? LEFT : RIGHT;
else
state_next <= FALL_R;
end
FALL_L : begin
if (ground)
state_next <= LEFT;
else
state_next <= FALL_L;
end
FALL_R : begin
if (ground)
state_next <= RIGHT;
else
state_next <= FALL_R;
end
endcase
end
always @(posedge clk, posedge areset) begin
if (areset)
state <= LEFT;
else
state <= state_next;
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = (state == FALL_R) | (state == FALL_L);
endmodule
HDLBits-131 Lemmings3
Problem Statement
另请参阅:Lemmings1和Lemmings2。
除了走路和摔倒之外,有时还可以要求Lemmings做一些有用的事情,例如挖掘(当dig = 1时就开始挖掘)。 如果一只Lemming目前正在地面上行走(ground= 1且没有掉落),它可以进行挖掘,并将继续挖掘直到到达另一侧(ground= 0)。 此时,由于没有地面,它将坠落(aaah!),然后一旦再次撞击地面,便继续沿其原始方向行走。 与掉落一样,在挖掘过程中发生碰撞无效,而在掉落或没有地面时被告知挖掘则被忽略。
(换句话说,行走的旅鼠会掉落,挖掘或切换方向。如果满足以上条件之一,则下降优先级高于挖掘,下降优先级高于切换方向。)
扩展上面的有限状态机以对这种行为进行建模。
状态转换图如下所示:
代码如下:
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=0, right=1, left_ground =2, right_ground=3, left_dig=4, right_dig=5;
reg [2:0] state, state_next;
always @(*) begin
case (state)
left : begin
if (ground) begin
if (dig)
state_next <= left_dig;
else
state_next <= bump_left ? right : left;
end
else
state_next <= left_ground;
end
right : begin
if (ground) begin
if (dig)
state_next <= right_dig;
else
state_next <= bump_right ? left : right;
end
else
state_next <= right_ground;
end
left_ground : begin
if (ground)
state_next <= left;
else
state_next <= left_ground;
end
right_ground : begin
if (ground)
state_next <= right;
else
state_next <= right_ground;
end
left_dig : begin
if (ground)
state_next <= left_dig;
else
state_next <= left_ground;
end
right_dig : begin
if (ground)
state_next <= right_dig;
else
state_next <= right_ground;
end
endcase
end
always @(posedge clk, posedge areset) begin
if (areset)
state <= left;
else
state <= state_next;
end
assign walk_left = (state == left);
assign walk_right = (state == right);
assign aaah = (state == left_ground) | (state == right_ground);
assign digging = (state == left_dig) | (state == right_dig);
endmodule
HDLBits-132 Lemmings4
Problem Statement
另请参阅:Lemmings1,Lemmings2和Lemmings3。
尽管Lemmings可以行走,掉落和挖土,但Lemmings并不是无敌的。 如果Lemmings掉落的时间过长,然后撞到地面,它可能会飞溅。 特别是,如果Lemming掉落超过20个时钟周期然后撞到地面,它将永久飞溅(并且直到4个输出变为0)(或直到FSM复位),然后停止行走,掉落或挖掘(全部4个输出变为0)。 旅鼠在撞上地面之前可以跌落的距离没有上限。 只在撞到地面时会飞溅; 他们不会在空中飞溅。
扩展之前的有限状态机以对这种行为进行建模。
下降20个周期是可以生存的:
下降21个周期会导致飞溅:
状态转换图如下所示:
代码如下:
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'd0, right=3'd1, falll=3'd2, fallr=3'd3, digl=3'd4, digr=3'd5, splat=3'd6;
reg [2:0] state, next_state;
reg [31:0] count;
always@(posedge clk or posedge areset) begin
if(areset)
state <= left;
else if(state == falll || state == fallr) begin
state <= next_state;
count <= count + 1;
end
else begin
state <= next_state;
count <= 0;
end
end
always@(*) begin
case(state)
left: begin
if(~ground) next_state = falll;
else if(dig) next_state = digl;
else if(bump_left) next_state = right;
else next_state = left;
end
right: begin
if(~ground) next_state = fallr;
else if(dig) next_state = digr;
else if(bump_right) next_state = left;
else next_state = right;
end
falll: begin
if(ground) begin
if(count>19) next_state = splat;
else next_state = left;
end
else next_state = falll;
end
fallr: begin
if(ground) begin
if(count>19) next_state = splat;
else next_state = right;
end
else next_state = fallr;
end
digl: begin
if(ground) next_state = digl;
else next_state = falll;
end
digr: begin
if(ground) next_state = digr;
else next_state = fallr;
end
splat: begin
next_state = splat;
end
endcase
end
assign walk_left = (state == left);
assign walk_right = (state == right);
assign aaah = (state == falll || state == fallr);
assign digging = (state == digl || state == digr);
endmodule
Note
新手一枚,主要分享博客,记录学习过程,后期参考大佬代码或思想会一一列出。欢迎大家批评指正!