10、旅鼠1
在旅鼠的 2D 世界中,旅鼠可以处于两种状态之一:向左走或向右走。如果碰到障碍物,它会改变方向。特别是,如果旅鼠在左边被撞到,它会向右走。如果它在右边被撞到,它会向左走。如果它同时在两侧碰撞,它仍然会转换方向。
实现一个具有两个状态、两个输入和一个输出的摩尔状态机来模拟这种行为。
提示:
代码实现:
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=1'b0, RIGHT=1'b1;
reg state, next_state;
always @(*) begin
case(state) // State transition logic
LEFT:begin
if( bump_left == 1'b1 )
next_state <= RIGHT;
else
next_state <= LEFT;
end
RIGHT:begin
if( bump_right == 1'b1 )
next_state <= LEFT;
else
next_state <= RIGHT;
end
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state <= LEFT;
else
state <= next_state;// State flip-flops with asynchronous reset
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
endmodule
验证结果:
11、旅鼠2
除了左右走,旅鼠会摔倒(并且大概会“啊啊!”)如果地面消失在它们下面。
除了左右行走和碰撞时改变方向,当ground=0 时,旅鼠会摔倒并说“aaah!”。当地面重新出现(地面=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,AH_LEFT=2'b10,AH_RIGHT=2'b11;
reg [1:0] state, next_state;
wire [1:0] bump;
assign bump = {bump_left,bump_right};
always @(*) begin
case(state) // State transition logic
LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else if( bump == 2'b10 || bump == 2'b11)
next_state <= RIGHT;
else
next_state <= LEFT;
end
RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else if( bump == 2'b01 || bump == 2'b11)
next_state <= LEFT;
else
next_state <= RIGHT;
end
AH_LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else
next_state <= LEFT;
end
AH_RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else
next_state <= RIGHT;
end
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state <= LEFT;
else
state <= next_state;// State flip-flops with asynchronous reset
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT));
endmodule
验证结果:
12、旅鼠3
除了行走和跌倒之外,有时还可以让旅鼠做一些有用的事情,比如挖掘(当dig=1时它开始挖掘)。如果旅鼠当前正在地面上行走(地面=1并且没有下落),它可以挖掘,并且会继续挖掘直到到达另一侧(地面=0)。那个时候,因为没有地面,它会掉下来(啊啊!),然后一旦它再次撞到地面就继续沿着原来的方向走。与坠落一样,在挖掘时被撞到没有任何影响,并且在坠落或没有地面时被告知要挖掘被忽略。
(换句话说,一只行走的旅鼠可以跌倒、挖掘或切换方向。如果满足以上条件中的一个,则fall的优先级高于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,AH_LEFT=3'b010,AH_RIGHT=3'b011,DIG_LEFT=3'b100,DIG_RIGHT=3'b101;
reg [2:0] state, next_state;
wire [1:0] bump;
assign bump = {bump_left,bump_right};
always @(*) begin
case(state) // State transition logic
LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else if( dig ==1'b1 )
next_state <= DIG_LEFT;
else if( bump == 2'b10 || bump == 2'b11)
next_state <= RIGHT;
else
next_state <= LEFT;
end
RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else if( dig ==1'b1 )
next_state <= DIG_RIGHT;
else if( bump == 2'b01 || bump == 2'b11)
next_state <= LEFT;
else
next_state <= RIGHT;
end
AH_LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else
next_state <= LEFT;
end
AH_RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else
next_state <= RIGHT;
end
DIG_LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else
next_state <= DIG_LEFT;
end
DIG_RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else
next_state <= DIG_RIGHT;
end
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state <= LEFT;
else
state <= next_state;// State flip-flops with asynchronous reset
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT));
assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
endmodule
验证结果:
13、旅鼠4
尽管旅鼠可以行走、跌倒和挖掘,但旅鼠并非无懈可击。如果旅鼠掉得太久然后撞到地面,它可能会飞溅。特别是,如果旅鼠跌落超过 20 个时钟周期然后撞到地面,它将永远(或直到 FSM 重置)溅出并停止行走、跌落或挖掘(所有 4 个输出都变为 0)。旅鼠在落地前可以跌落多远没有上限。旅鼠只会在落地时溅起水花;它们不会在半空中飞溅。
扩展您的有限状态机来模拟这种行为。
跌倒 20 个周期是可以存活的:
下降 21 个周期会导致飞溅:
提示:使用 FSM 来控制一个计数器,该计数器跟踪旅鼠下降的时间。
代码实现:
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,AH_LEFT=3'b010,AH_RIGHT=3'b011;
parameter DIG_LEFT=3'b100,DIG_RIGHT=3'b101,SPLAT=3'b110,DEAD=3'b111;
reg [2:0] state, next_state;
wire [1:0] bump;
wire [4:0] cycle_count;
assign bump = {bump_left,bump_right};
always @(posedge clk, posedge areset) begin
if(areset)
cycle_count <= 5'd0;
else if((next_state == AH_LEFT) || (next_state == AH_RIGHT))
cycle_count <= cycle_count + 1'b1;
else
cycle_count <= 5'd0;
end
always @(*) begin
case(state) // State transition logic
LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else if( dig ==1'b1 )
next_state <= DIG_LEFT;
else if( bump == 2'b10 || bump == 2'b11)
next_state <= RIGHT;
else
next_state <= LEFT;
end
RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else if( dig ==1'b1 )
next_state <= DIG_RIGHT;
else if( bump == 2'b01 || bump == 2'b11)
next_state <= LEFT;
else
next_state <= RIGHT;
end
AH_LEFT:begin
if((ground ==1'b0) &&(cycle_count < 5'd20))
next_state <= AH_LEFT;
else if((ground ==1'b0) &&(cycle_count >= 5'd20))
next_state <= SPLAT;
else
next_state <= LEFT;
end
AH_RIGHT:begin
if((ground ==1'b0) &&(cycle_count < 5'd20))
next_state <= AH_RIGHT;
else if((ground ==1'b0) &&(cycle_count >= 5'd20))
next_state <= SPLAT;
else
next_state <= RIGHT;
end
DIG_LEFT:begin
if( ground ==1'b0 )
next_state <= AH_LEFT;
else
next_state <= DIG_LEFT;
end
DIG_RIGHT:begin
if( ground ==1'b0 )
next_state <= AH_RIGHT;
else
next_state <= DIG_RIGHT;
end
SPLAT:begin
if( ground ==1'b1 )
next_state <= DEAD;
else
next_state <= SPLAT;
end
DEAD:
next_state <= DEAD;
endcase
end
always @(posedge clk, posedge areset) begin
if(areset)
state <= LEFT;
else
state <= next_state;// State flip-flops with asynchronous reset
end
// Output logic
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT) || (state == SPLAT));
assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
endmodule
验证结果:
14、One-hot FSM
独热码,给定以下具有 1 个输入和 2 个输出的状态机:
根据状态转移图输出下一状态与结果。
代码实现:
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
parameter S0=4'd0,S1=4'd1,S2=4'd2,S3=4'd3,S4=4'd4;
parameter S5=4'd5,S6=4'd6,S7=4'd7,S8=4'd8,S9=4'd9;
assign next_state[0] = ~in & (state[S0]|state[S1]|state[S2]|state[S3]|state[S4]|state[S7]|state[S8]|state[S9]);
assign next_state[1] = in & (state[S0]|state[S8]|state[S9]);
assign next_state[2] = in & state[S1];
assign next_state[3] = in & state[S2];
assign next_state[4] = in & state[S3];
assign next_state[5] = in & state[S4];
assign next_state[6] = in & state[S5];
assign next_state[7] = in & (state[S6]|state[S7]);
assign next_state[8] = ~in & state[S5];
assign next_state[9] = ~in & state[S6];
assign out1 = (state[S8] || state[S9]);
assign out2 = (state[S7] || state[S9]);
endmodule
验证结果: