HDLBits/Sequential Logic/Finite State Machines/Lemmings4
Although Lemmings can walk, fall, and dig, Lemmings aren't invulnerable. If a Lemming falls for too long then hits the ground, it can splatter. In particular, if a Lemming falls for more than 20 clock cycles then hits the ground, it will splatter and cease walking, falling, or digging (all 4 outputs become 0), forever (Or until the FSM gets reset). There is no upper limit on how far a Lemming can fall before hitting the ground. Lemmings only splatter when hitting the ground; they do not splatter in mid-air.
Extend your finite state machine to model this behaviour.
Falling for 20 cycles is survivable:
Game Lemmings4:小人行動規則與上述規則相同,添加小人會die的規則:
如果小人fall超過20cycles,則當其接觸地面時直接die(未接觸地面時不會die) dig,fall,left和right輸出全部置零,直到reset信號來臨。
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'b0;
parameter RIGHT = 3'b1;
parameter DIG_LEFT = 3'b10;
parameter DIG_RIGHT = 3'b11;
parameter FALL_LEFT = 3'b100;
parameter FALL_RIGHT = 3'b101;
parameter DEAD = 3'b110;
parameter SPLATTER = 3'b111;
reg [2:0] state,next_state;
reg [4:0] Cycle_Count;
wire [1:0] bump;
assign bump = {bump_left,bump_right};
always @(*)begin
case(state)
LEFT:begin
if(ground == 1'b0)begin
next_state <= FALL_LEFT;
end
else if(dig == 1'b1)begin
next_state <= DIG_LEFT;
end
else if((bump == 2'b10) || (bump == 2'b11))begin
next_state <= RIGHT;
end
else begin
next_state <= LEFT;
end
end
RIGHT:begin
if(ground == 1'b0)begin
next_state <= FALL_RIGHT;
end
else if(dig == 1'b1)begin
next_state <= DIG_RIGHT;
end
else if((bump == 2'b01) || (bump == 2'b11))begin
next_state <= LEFT;
end
else begin
next_state <= RIGHT;
end
end
DIG_LEFT:begin
if(ground == 1'b0)begin
next_state <= FALL_LEFT;
end
else begin
next_state <= DIG_LEFT;
end
end
DIG_RIGHT:begin
if(ground == 1'b0)begin
next_state <= FALL_RIGHT;
end
else begin
next_state <= DIG_RIGHT;
end
end
FALL_LEFT:begin
if((ground == 1'b0) && (Cycle_Count < 5'd20))begin
next_state <= FALL_LEFT;
end
else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin
next_state <= SPLATTER;
end
else begin
next_state <= LEFT;
end
end
FALL_RIGHT:begin
if((ground == 1'b0) && (Cycle_Count < 5'd20))begin
next_state <= FALL_RIGHT;
end
else if((ground == 1'b0) && (Cycle_Count >= 5'd20))begin
next_state <= SPLATTER;
end
else begin
next_state <= RIGHT;
end
end
SPLATTER:begin
if(ground == 1'b1)begin
next_state <= DEAD;
end
else begin
next_state <= SPLATTER;
end
end
DEAD:begin
next_state <= DEAD;
end
endcase
end
always @(posedge clk,posedge areset)begin
if(areset)begin
state <= LEFT;
end
else begin
state <= next_state;
end
end
always @(posedge clk,posedge areset)begin
if(areset)begin
Cycle_Count <= 5'd0;
end
else if((next_state == FALL_LEFT) || (next_state == FALL_RIGHT)) begin
Cycle_Count <= Cycle_Count + 1'b1;
end
else begin
Cycle_Count <= 5'd0;
end
end
assign walk_left = (state == LEFT);
assign walk_right = (state == RIGHT);
assign aaah = ((state == FALL_LEFT) || (state == FALL_RIGHT) || (state == SPLATTER));
assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
endmodule
沒有留言:
張貼留言