HDLBits第十四章练习及答案2

10、旅鼠1

在旅鼠的 2D 世界中,旅鼠可以处于两种状态之一:向左走或向右走。如果碰到障碍物,它会改变方向。特别是,如果旅鼠在左边被撞到,它会向右走。如果它在右边被撞到,它会向左走。如果它同时在两侧碰撞,它仍然会转换方向。

实现一个具有两个状态、两个输入和一个输出的摩尔状态机来模拟这种行为。
在这里插入图片描述
提示:
在这里插入图片描述

代码实现:

module top_module(
    input clk,
    input areset,    // Freshly brainwashed Lemmings walk left.
    input bump_left,
    input bump_right,
    output walk_left,
    output walk_right); //  

    parameter LEFT=1'b0, RIGHT=1'b1;
    reg state, next_state;

    always @(*) begin
        case(state)     // State transition logic
            LEFT:begin
            if( bump_left == 1'b1 )
                next_state <= RIGHT;
            else
                next_state <= LEFT;   
            end    
            RIGHT:begin
            if( bump_right == 1'b1 )
                next_state <= LEFT;
            else
                next_state <= RIGHT;   
            end
        endcase
    end

    always @(posedge clk, posedge areset) begin
        if(areset)
            state <= LEFT;
        else
            state <= next_state;// State flip-flops with asynchronous reset
    end

    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);

endmodule

验证结果:
在这里插入图片描述

11、旅鼠2

除了左右走,旅鼠会摔倒(并且大概会“啊啊!”)如果地面消失在它们下面。

除了左右行走和碰撞时改变方向,当ground=0 时,旅鼠会摔倒并说“aaah!”。当地面重新出现(地面=1)时,旅鼠将继续沿与坠落前相同的方向行走。跌倒时被撞到不影响行走方向,被撞在与地面消失(但尚未落下)相同的循环中,或当地面重新出现时仍在跌倒时,也不影响行走方向。

构建一个有限状态机来模拟这种行为。
在这里插入图片描述
提示:
在这里插入图片描述

代码实现:

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 LEFT=2'b00, RIGHT=2'b01,AH_LEFT=2'b10,AH_RIGHT=2'b11;
    reg [1:0] state, next_state;
    wire [1:0] bump;
    
    assign bump = {bump_left,bump_right};
        
    always @(*) begin
        case(state)     // State transition logic
            LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else if( bump == 2'b10 || bump == 2'b11)
                next_state <= RIGHT;
            else
                next_state <= LEFT;   
            end  
            RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
                else if( bump == 2'b01 || bump == 2'b11)
                next_state <= LEFT;
            else
                next_state <= RIGHT;   
            end 
            AH_LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else
                next_state <= LEFT;   
            end    
            AH_RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else
                next_state <= RIGHT;   
            end              
        endcase
    end

    always @(posedge clk, posedge areset) begin
        if(areset)
            state <= LEFT;
        else
            state <= next_state;// State flip-flops with asynchronous reset
    end

    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT));
    
endmodule

验证结果:
在这里插入图片描述

12、旅鼠3

除了行走和跌倒之外,有时还可以让旅鼠做一些有用的事情,比如挖掘(当dig=1时它开始挖掘)。如果旅鼠当前正在地面上行走(地面=1并且没有下落),它可以挖掘,并且会继续挖掘直到到达另一侧(地面=0)。那个时候,因为没有地面,它会掉下来(啊啊!),然后一旦它再次撞到地面就继续沿着原来的方向走。与坠落一样,在挖掘时被撞到没有任何影响,并且在坠落或没有地面时被告知要挖掘被忽略。

(换句话说,一只行走的旅鼠可以跌倒、挖掘或切换方向。如果满足以上条件中的一个,则fall的优先级高于dig,后者的优先级高于切换方向。)

扩展您的有限状态机来模拟这种行为。
在这里插入图片描述
提示:
在这里插入图片描述

代码实现:

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'b000, RIGHT=3'b001,AH_LEFT=3'b010,AH_RIGHT=3'b011,DIG_LEFT=3'b100,DIG_RIGHT=3'b101;
    reg [2:0] state, next_state;
    wire [1:0] bump; 
    
    assign bump = {bump_left,bump_right};
    
    always @(*) begin
        case(state)     // State transition logic
            LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else if( dig ==1'b1 ) 
                next_state <= DIG_LEFT;    
            else if( bump == 2'b10 || bump == 2'b11)
                next_state <= RIGHT;
            else
                next_state <= LEFT;   
            end  
            RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else if( dig ==1'b1 ) 
                next_state <= DIG_RIGHT;      
            else if( bump == 2'b01 || bump == 2'b11)
                next_state <= LEFT;
            else
                next_state <= RIGHT;   
            end 
            AH_LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else
                next_state <= LEFT;   
            end    
            AH_RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else
                next_state <= RIGHT;   
            end
            DIG_LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else
                next_state <= DIG_LEFT;   
            end 
            DIG_RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else
                next_state <= DIG_RIGHT;   
            end      
        endcase
    end    

    always @(posedge clk, posedge areset) begin
        if(areset)
            state <= LEFT;
        else
            state <= next_state;// State flip-flops with asynchronous reset
    end

    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT));
    assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
    
endmodule

验证结果:
在这里插入图片描述

13、旅鼠4

尽管旅鼠可以行走、跌倒和挖掘,但旅鼠并非无懈可击。如果旅鼠掉得太久然后撞到地面,它可能会飞溅。特别是,如果旅鼠跌落超过 20 个时钟周期然后撞到地面,它将永远(或直到 FSM 重置)溅出并停止行走、跌落或挖掘(所有 4 个输出都变为 0)。旅鼠在落地前可以跌落多远没有上限。旅鼠只会在落地时溅起水花;它们不会在半空中飞溅。

扩展您的有限状态机来模拟这种行为。

跌倒 20 个周期是可以存活的:
在这里插入图片描述
下降 21 个周期会导致飞溅:
在这里插入图片描述
提示:使用 FSM 来控制一个计数器,该计数器跟踪旅鼠下降的时间。
在这里插入图片描述
代码实现:

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'b000, RIGHT=3'b001,AH_LEFT=3'b010,AH_RIGHT=3'b011;
    parameter DIG_LEFT=3'b100,DIG_RIGHT=3'b101,SPLAT=3'b110,DEAD=3'b111;
    reg [2:0] state, next_state;
    wire [1:0] bump; 
    wire [4:0] cycle_count;
    
    assign bump = {bump_left,bump_right};

    always @(posedge clk, posedge areset) begin
        if(areset)
            cycle_count <= 5'd0;
        else if((next_state == AH_LEFT) || (next_state == AH_RIGHT))
            cycle_count <= cycle_count + 1'b1;
        else
            cycle_count <= 5'd0;            
    end
    
    always @(*) begin
        case(state)     // State transition logic
            LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else if( dig ==1'b1 ) 
                next_state <= DIG_LEFT;    
            else if( bump == 2'b10 || bump == 2'b11)
                next_state <= RIGHT;
            else
                next_state <= LEFT;   
            end  
            RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else if( dig ==1'b1 ) 
                next_state <= DIG_RIGHT;      
            else if( bump == 2'b01 || bump == 2'b11)
                next_state <= LEFT;
            else
                next_state <= RIGHT;   
            end 
            AH_LEFT:begin
            if((ground ==1'b0) &&(cycle_count < 5'd20)) 
                next_state <= AH_LEFT;
            else if((ground ==1'b0) &&(cycle_count >= 5'd20))
                next_state <= SPLAT;
            else    
                next_state <= LEFT;   
            end    
            AH_RIGHT:begin
            if((ground ==1'b0) &&(cycle_count < 5'd20)) 
                next_state <= AH_RIGHT;
            else if((ground ==1'b0) &&(cycle_count >= 5'd20))
                next_state <= SPLAT;     
            else
                next_state <= RIGHT;   
            end
            DIG_LEFT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_LEFT;
            else
                next_state <= DIG_LEFT;   
            end 
            DIG_RIGHT:begin
            if( ground ==1'b0 ) 
                next_state <= AH_RIGHT;
            else
                next_state <= DIG_RIGHT;   
            end   
            SPLAT:begin
                if( ground ==1'b1 ) 
                next_state <= DEAD;
            else
                next_state <= SPLAT;   
            end  
            DEAD:
                next_state <= DEAD;
        endcase
    end    

    always @(posedge clk, posedge areset) begin
        if(areset)
            state <= LEFT;
        else
            state <= next_state;// State flip-flops with asynchronous reset
    end

    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
    assign aaah = ((state == AH_LEFT) || (state == AH_RIGHT) || (state == SPLAT));
    assign digging = ((state == DIG_LEFT) || (state == DIG_RIGHT));
    
endmodule

验证结果:
在这里插入图片描述

14、One-hot FSM

独热码,给定以下具有 1 个输入和 2 个输出的状态机:
在这里插入图片描述
根据状态转移图输出下一状态与结果。

代码实现:

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);

    parameter S0=4'd0,S1=4'd1,S2=4'd2,S3=4'd3,S4=4'd4;
    parameter S5=4'd5,S6=4'd6,S7=4'd7,S8=4'd8,S9=4'd9;
    
    assign next_state[0] = ~in & (state[S0]|state[S1]|state[S2]|state[S3]|state[S4]|state[S7]|state[S8]|state[S9]);
    assign next_state[1] = in & (state[S0]|state[S8]|state[S9]);
    assign next_state[2] = in & state[S1];
    assign next_state[3] = in & state[S2];
    assign next_state[4] = in & state[S3];
    assign next_state[5] = in & state[S4];
    assign next_state[6] = in & state[S5];
    assign next_state[7] = in & (state[S6]|state[S7]);
    assign next_state[8] = ~in & state[S5];
    assign next_state[9] = ~in & state[S6];
    
    assign out1 = (state[S8] || state[S9]);
    assign out2 = (state[S7] || state[S9]);
    
endmodule

验证结果:
在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值