Verilog HDLbits:Lemmings4(Moore型有限元状态机)

题目

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.
Verilog HDLbits:Lemmings4(Moore型有限元状态机)_第1张图片
Verilog HDLbits:Lemmings4(Moore型有限元状态机)_第2张图片

解题思路

Lemmings3相比Lemmings4需要多加一个状态以及一个计数器。当left_falll或者right_fall的持续时间超过20个时钟周期时就进入die状态,直到系统复位。

代码如下

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;
    parameter right = 1;
    parameter left_dig = 2;
    parameter right_dig = 3;
    parameter left_fall = 4;
    parameter right_fall = 5;
    parameter die = 6;
    
    reg[2:0] state, next_state;
    reg[3:0] out;
    reg [4:0] cnt;
    reg flag;
    //fall状态计数器
     always@(posedge clk or posedge areset) begin
        if(areset)
          cnt <= 0;    
         else if(!ground)//或者写成(state==left_fall||state==right_fall)
             cnt<= cnt+1'b1;
         else if(!ground)
             cnt<=cnt+1'b1;
         else 
             cnt<=0;
    end
    //当fall状态超过20个时钟周期时,拉高flag信号
    always@(posedge clk or posedge areset) begin
        if(areset) 
            flag<=1'b0;
        else if(cnt==20)
            
         flag<=1;
        else 
         flag<=flag;
         end
   
    always@(posedge clk or posedge areset) begin
        if(areset)
            state <= left;
        else
            state <= next_state;
    end
    
    //transition(状态转移描述)
    
    always@(*) begin
        case(state)
            left:begin
              if(!ground)
                    next_state=left_fall;
                else if(dig)
                    next_state=left_dig;
                else if(bump_left)
                    next_state=right;
                else 
                    next_state=left;
                    end
                    
             right:begin
              if(!ground)
                    next_state=right_fall;
                else if(dig)
                    next_state=right_dig;
                 else if(bump_right)
                    next_state=left;
                else
                    next_state=right;
                    end
                    
            left_dig:begin
                if(!ground)
                    next_state=left_fall;
                else
                    next_state=left_dig;
            end
            
           right_dig:begin
            if(!ground)
                    next_state=right_fall;
                else
                    next_state=right_dig;
            end
            //-------------------分界线---------------------//
            //分界线之前的状态描述与*Lemmings3*相同
              right_fall:begin
             if(!ground)
                    next_state=right_fall;
                  else
                      if(flag)
                          next_state<=die;//flag为高电平时进入die状态
                  else
                      next_state=right;
              end
                left_fall:begin
                   
                if(!ground)
                    next_state=left_fall;
                  else
                      if(flag)
                          next_state<=die;
                    else
                      next_state=left;
                   end
         die:begin
             next_state=die;//进入die状态后保持
         end
   
        endcase
    end
    
   
    always@(posedge clk or posedge areset) begin
        if(areset)
            out <= 4'b1000;
        else
            case(next_state)
                left: out <= 4'b1000;
                left_dig: out <= 4'b0001;
                left_fall: out <= 4'b0010;
                right: out <= 4'b0100;
                right_dig: out <= 4'b0001;
                right_fall: out <= 4'b0010;
                die:out<=4'b0000;
            endcase
    end
    
    assign {walk_left, walk_right, aaah, digging} = out;
    
endmodule

你可能感兴趣的:(HDLbits,fpga,verilog)