题目
地址:HDLBits - Lemmings3
详细:
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.
Extend your finite state machine to model this behaviour.
Module Declaration
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 );
分析
- 其他参考HDLBits在线练习题之Lemmings2
- 四个状态:FALL, DIGGING, LEFT, RIGHT
- 除非reset,DIGGING的结束是因为ground为0,所以state_before_fall保存的应该在dig为1时的状态。
代码
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=2'b00,RIGHT=2'b01,FALL=2'b11,DIGGING=2'b10;
reg [1:0] current_state,next_state,state_before_fall;
always @(posedge clk or posedge areset) begin
if (areset) begin
state_before_fall <= LEFT;
end
else if (dig && (current_state==LEFT || current_state==RIGHT)) begin
state_before_fall <= current_state;
end
else begin
state_before_fall <= state_before_fall;
end
end
always @(*) begin
if (ground) begin
case (current_state)
LEFT: begin
if (dig) begin
next_state = DIGGING;
end
else if (bump_left) begin
next_state = RIGHT;
end
else begin
next_state = LEFT;
end
end
RIGHT: begin
if (dig) begin
next_state = DIGGING;
end
else if (bump_right) begin
next_state = LEFT;
end
else begin
next_state = RIGHT;
end
end
FALL: begin
next_state = state_before_fall;
end
DIGGING: begin
next_state = DIGGING;
end
default:
next_state <= LEFT;
endcase
end
else begin
next_state = FALL;
end
end
always @(posedge clk,posedge areset) begin
if (areset) begin
current_state <= LEFT;
end
else begin
current_state <= next_state;
end
end
assign walk_left = (current_state==LEFT)?1'b1:1'b0;
assign walk_right = (current_state==RIGHT)?1'b1:1'b0;
assign aaah = (current_state==FALL)?1'b1:1'b0;
assign digging = (current_state==DIGGING)?1'b1:1'b0;
endmodule