HDLbits: Lemmings3

Lemmings又多了一种状态:dig,我按照上一篇文章里大神的思路又多加了两种状态:LEFT_DIGGING与RIGHT_DIGGING,写出了如下的代码:

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=4'b000001, RIGHT=4'b000010, LEFT_FALLING=4'b000100, RIGHT_FALLING=4'b001000, 
        LEFT_DIGGING=4'b010000, RIGHT_DIGGING=4'b100000;
        
    reg [3:0] state,next_state;

    always@(*)begin
        case(state)
            LEFT: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING;                    
            RIGHT: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING;  
            LEFT_FALLING: next_state = ground?LEFT:LEFT_FALLING;
            RIGHT_FALLING: next_state = ground?RIGHT:RIGHT_FALLING;
            LEFT_DIGGING: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING;
            RIGHT_DIGGING: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING;
            default: next_state = LEFT;
        endcase            
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)
          state <= LEFT;
        else
          state <= next_state;
    end
    
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = (state == LEFT_FALLING || state == RIGHT_FALLING);
    assign digging = (state == RIGHT_DIGGING || state == LEFT_DIGGING);        

endmodule

跑出来有错误,检查了时序图,发现这道题目跟我理解的不一致,我以为input中的dig一直为1时,lemming才一直挖地,原来是只要dig输入过1,lemming会一直挖地直到尽头。然后我改掉了LEFT_DIGGING和RIGHT_DIGGING的状态转换的条件,得到如下的代码:

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=4'b000001, RIGHT=4'b000010, LEFT_FALLING=4'b000100, RIGHT_FALLING=4'b001000, 
        LEFT_DIGGING=4'b010000, RIGHT_DIGGING=4'b100000;
        
    reg [3:0] state,next_state;

    always@(*)begin
        case(state)
            LEFT: next_state = ground?(dig?LEFT_DIGGING:(bump_left?RIGHT:LEFT)):LEFT_FALLING;                    
            RIGHT: next_state = ground?(dig?RIGHT_DIGGING:(bump_right?LEFT:RIGHT)):RIGHT_FALLING;  
            LEFT_FALLING: next_state = ground?LEFT:LEFT_FALLING;
            RIGHT_FALLING: next_state = ground?RIGHT:RIGHT_FALLING;
            LEFT_DIGGING: next_state = ground?LEFT_DIGGING:LEFT_FALLING;
            RIGHT_DIGGING: next_state = ground?RIGHT_DIGGING:RIGHT_FALLING;
            default: next_state = LEFT;
        endcase            
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)
          state <= LEFT;
        else
          state <= next_state;
    end
    
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = (state == LEFT_FALLING || state == RIGHT_FALLING);
    assign digging = (state == RIGHT_DIGGING || state == LEFT_DIGGING);        

endmodule

仍然有错误,是在RIGHT状态下的bump_right和dig两个输入同时为1的时候出了问题,lemming一开始的反应去挖地了,没有问题,但是挖完地以后改变了方向变成了LEFT_DIGGING,而参考答案中没有改变方向是RIGHT_DIGGING。

HDLbits: Lemmings3_第1张图片然后检查到这里我发现一个大问题,我的parameter和和state的长度不对?!那时序图怎么跑到1940才发现错误呢?把parameter和state的长度改正之后终于success了。

按照我错误的写法,LEFT_DIGGING和RIGHT_DIGGING应该会被视为一种状态,所以只会执行case中排在前面的LEFT_DIGGING的状态转换,所以不会影响LEFT_DIGGING,只会影响RIGHT_DIGGING。因此导致了上面的错误。所以case里的条件是有顺序的,排在前面的匹配了后面的就不检查了?为了验证这个猜测,我把case里LEFT_DIGGING和RIGHT_DIGGING交换了位置,把RIGHT_DIGGING放在了前面,果然影响到了LEFT_DIGGING。

你可能感兴趣的:(verilog学习)