HDLBits刷题Day27,3.2.5.13 Lemmings 4

3.2.5.13  Lemmings 4

问题描述

虽然旅鼠可以行走、摔倒和挖掘,但旅鼠并非刀枪不入。如果旅鼠摔倒的时间过长,然后撞到地面,就会飞溅。特别是,如果旅鼠跌落超过 20 个时钟周期后撞到地面,它就会飞溅,并永远停止行走、跌落或挖掘(所有 4 个输出都变为 0)(或直到 FSM 被重置)。旅鼠在落地前的下落距离没有上限。旅鼠只有在落地时才会飞溅,在半空中不会飞溅。

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

分析:相比于lemmings1-lemmings3,本题多出了以下情况

  • 需要设置一个计数器count来记录下落周期数
  • 在state=fall_l或state=fall_r时,加入count判断条件
  • 多出两种状态,splatter表示下落超过20周期但还未碰地,dead表示下落超过20周期且碰地

关于计数器如下(解释代码中为什么将count的初值设为1)

代码:

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'd0,right=3'd1,dig_l=3'd2,dig_r=3'd3,fall_l=3'd4,fall_r=3'd5,splatter=3'd6,dead=3'd7;
    reg [3:0] state,next_state;
    reg [4:0] count;   //计数器
    

    // 这里把count的初值设为了1,原因可以看画的图
    always @(posedge clk,posedge areset) begin
        if(areset)
            count<=1;
        else if(next_state==fall_l || next_state==fall_r)
            count<=count+1;
        else
            count<=1;
    end
    
    always @(*) begin
        case(state)
            left:begin
                if(!ground)
                    next_state=fall_l; //判断是否落下
                else if(dig)
                    next_state=dig_l;  //不落下,判断是否挖掘
                else if(bump_left)
                    next_state=right;  //不挖掘,判断是否碰壁
                else
                    next_state=left;
            end
            
            right:begin
                if(!ground)
                    next_state=fall_r;
                else if(dig)
                    next_state=dig_r;
                else if(bump_right)
                    next_state=left;
                else
                    next_state=right;
            end
            
            dig_l:begin
                if(!ground)
                    next_state=fall_l;
                else
                    next_state=dig_l;
            end
            
            dig_r:begin
                if(!ground)
                    next_state=fall_r;
                else
                    next_state=dig_r;
            end
         
            fall_l:begin
                if(!ground && count<=20)
                    next_state<=fall_l; //不超过20周期
                else if(!ground && count>20)
                    next_state<=splatter;
                else 
                    next_state<=left;
            end
            fall_r:begin
                if(!ground && count<=20)
                    next_state<=fall_r; //不超过20周期
                else if(!ground && count>20)
                    next_state<=splatter;
                else 
                    next_state<=right;
            end
            splatter:begin
                if(ground)
                    next_state<=dead;
                else
                    next_state<=splatter;
            end
            dead:begin
                next_state<=dead;
            end
        endcase
    end
            
                   
    always @(posedge clk,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 == fall_l)||(state == fall_r)||(state == splatter));
    assign digging = ((state == dig_l)||(state == dig_r));
        
endmodule

3.28补充:计数器的always模块和时序转移部分的always模块是并行的,所以能在count计数改变的同时更新state的状态

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值