2021年5月2日 星期日

HBLbits_Verilog Basic_Lemmings4

 HBLbits_Verilog Basic_Lemmings4

See also: Lemmings1Lemmings2, 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

沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...