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:
- 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,FALLL=2,FALLR=3,DIGL=4,DIGR=5,DIE=6;
- parameter DIE_CLOCK=19;
- //fall分出左右更有利于编程,dig应该也是这样
- reg [2:0]state, next_state;
- reg [4:0]die_count;
- /*我原计划把这里die_count设置成足够大的位数(12位),让它一直掉也无所谓。后来还是报错。
- 所以只好设置一个signal表示该死了,把die_count控制在最高19*/
- reg signal;
- //这里两位状态寄存器,必须记住!
- always @(*) begin
- // State transition logic
- case(state)
- LEFT:next_state<=ground?(dig?DIGL:(bump_left?RIGHT:LEFT)):FALLL;
- RIGHT:next_state<=ground?(dig?DIGR:(bump_right?LEFT:RIGHT)):FALLR;
- //这里要记得ground判定在前
- FALLL:next_state<=ground?(signal?DIE:LEFT):FALLL;
- FALLR:next_state<=ground?(signal?DIE:RIGHT):FALLR;
- DIGL:next_state<=ground?DIGL:FALLL;
- DIGR:next_state<=ground?DIGR:FALLR;
- DIE:next_state<=DIE;
- endcase
- end
- //这里把是否死亡的测试摘出来单独成一个always
- always@(posedge clk,posedge areset) begin
- if(areset) begin
- signal<=0;
- die_count<=0;
- end
- else if(state==FALLL ||state==FALLR) begin
- if(die_count==19)
- signal<=1;
- else
- die_count<=die_count+1;
- end
- else begin
- die_count<=0;
- signal<=0;
- end
- end
- always @(posedge clk, posedge areset) begin
- // State flip-flops with asynchronous reset
- if(areset) begin
- state<=LEFT;
- //die_count<=0;
- end
- else begin
- state<=next_state;
- /*
- if(state==FALLL||state==FALLR)
- die_count<=die_count+1;
- else
- die_count<=0;
- */
- end
- end
-
- // Output logic
- assign walk_left = (state == LEFT);
- assign walk_right = (state == RIGHT);
- assign aaah=(state==FALLL||state==FALLR);
- assign digging=(state==DIGL||state==DIGR);
- endmodule