2021年7月4日 星期日

HDLBits/Sequential Logic/Finite State Machines/Lemmings4

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


沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...