HDLBits:状态机(FSM)之“Game Lemmings”

目录

Lemmings2

Lemmings3

Lemmings4


Lemmings2

题链接:Lemmings2 - HDLBits (01xz.net)

较之上一题引入一个 fall 态,题目看起来有点绕,从题中给定的提示图很容易理解。

HDLBits:状态机(FSM)之“Game Lemmings”_第1张图片

  • 由 fall 态返回需要保持原本掉落时的移动方向,于是将 fall 态巧妙地分为左、右移动时不同的两种 fall 状态,直观。
  • 处于 fall 态时 walk_left、walk_right 同时为低电平。
module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    input ground,
    output walk_left,
    output walk_right,
    output aaah ); 
    
    parameter L=2'b00, R=2'b01, L_fall=2'b10, R_fall=2'b11;
    reg [1:0] state, next_state;
    
    // state transition logic
    always @(*) begin
        case(state)
        L: next_state = ~ground ? L_fall : (bump_left ? R : L);
        R: next_state = ~ground ? R_fall : (bump_right ? L : R);
        L_fall: next_state = ~ground ? L_fall : L;
        R_fall: next_state = ~ground ? R_fall : R;
        endcase
    end
    
    always @(posedge clk or posedge areset) begin
        if(areset) state <= L;
        else begin
            aaah <= ~ground;
            state <= next_state;
        end
    end
    
    // walk_right = ~walk_left 不正确,和上题不同,此题左右移动不再全程相反
    // fall 时 walk_left 和 walk_right 都是低电平
    assign walk_left = (state == L);
    assign walk_right = (state == R); 

endmodule

Lemmings3

同理上一题,引入两个新的分左右 dig 状态即可。

Lemmings4

题链接:Lemmings4 - HDLBits (01xz.net)

HDLBits:状态机(FSM)之“Game Lemmings”_第2张图片

  •  较之题 Lemmings3 引入新状态 die,特点在于该状态不存在状态转移,进入该态则一直保持直到 areset。
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 L=3'd0, R=3'd1, L_fall=3'd2, R_fall=3'd3;
    parameter L_dig=3'd4, R_dig=3'd5;
    parameter die=3'd6; // cease 4 outputs state
    int count; // fall-clock
    reg [2:0] state, next_state;
    
    // state transition logic
    always @(*) begin
        case(state)
            L_dig: next_state = ground ? L_dig : L_fall;
            R_dig: next_state = ground ? R_dig : R_fall;
            L: next_state = ~ground ? L_fall : (dig ? L_dig : (bump_left ? R : L)); // fall > dig > switch
            R: next_state = ~ground ? R_fall : (dig ? R_dig : (bump_right ? L : R));
            L_fall: next_state = ~ground ? L_fall : (count>=20 ? die : L); // go to die when "count>=20" and "ground==1"
            R_fall: next_state = ~ground ? R_fall : (count>=20 ? die : R);
            die: next_state = die; // keep wait until areset
        endcase
    end
    
    always @(posedge clk or posedge areset) begin
        if(areset) begin
            state <= L;
            count = 0; // fall-clock clear
        end
        else begin
            if(state==next_state && (state==L_fall || state==R_fall))
                count <= count + 1;
            else count = 0;
            aaah <= (~ground & state!=die); // aaah 受 die 状态影响
            state <= next_state;
        end
    end
    
    assign walk_left = (state == L);
    assign walk_right = (state == R); 
    assign digging = (state == L_dig) | (state == R_dig);

endmodule

你可能感兴趣的:(数电基础,Verilog,verilog)