HBLbits_Verilog Basic_Lemmings4
See also: Lemmings1, Lemmings2, and Lemmings3.
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: 生存的
Falling for 21 cycles causes
splatter:飛濺
終於到了Lemmings系列問題的最終版,這回設定了摔死的情況,更加合理……即當Lemmings掉落過程超過20個時鐘週期,落地後就會掛掉。顯然這裡需要計數器進行計數,當計數器超過20的時候落地就會game over,所以這裡又多出了over的狀態。顯然不論是left_fall還是right_fall狀態,計數器計數超過20後都會進入over狀態,並且over狀態不能回到fall狀態,除非reset重定,所以over狀態不需要區分左右。
module top_module(
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 );
localparam left = 0;
localparam right = 1;
localparam left_dig = 2;
localparam right_dig = 3;
localparam left_fall = 4;
localparam right_fall = 5;
localparam over = 6;
reg[2:0] state, next_state;
reg[3:0] out;
reg[7:0] cnt;
always@(posedge clk or posedge areset) begin
if(areset)
state <= left;
else
state <= next_state;
end
always@(*) begin
case(state)
left:next_state=ground?(dig?left_dig:(bump_left?right:left)):left_fall;
right:next_state=ground?(dig?right_dig:(bump_right?left:right)):right_fall;
left_dig:next_state=ground?left_dig:left_fall;
right_dig:next_state=ground?right_dig:right_fall;
left_fall:next_state=ground?((cnt>=5'd21)?over:left):left_fall;
right_fall:next_state=ground?((cnt>=5'd21)?over:right):right_fall;
over:next_state=over;
endcase
end
always@(posedge clk or posedge areset) begin
if(areset) begin
out <= 4'b1000;
end
else
case(next_state)
left:begin
out <= 4'b1000;
cnt <= 0;
end
right:begin
out <= 4'b0100;
cnt <= 0;
end
left_dig:begin
out <= 4'b0001;
cnt <= 0;
end
right_dig:begin
out <= 4'b0001;
cnt <= 0;
end
left_fall:begin
out <= 4'b0010;
cnt = cnt + 1;
end
right_fall:begin
out <= 4'b0010;
cnt = cnt + 1;
end
over:out <= 4'b0000;
endcase
end
assign {walk_left, walk_right, aaah, digging} = out;
endmodule
沒有留言:
張貼留言