HDLBits(【FSM】-水库及旅鼠 日常记录方便回看)

HDLBits答案记录【FSM-水库供水实践题】(仅用于自己答案记录)
这里虽然是三段式状态机,但是和二段式状态机(输出判断的是state)更像。三段式状态机的输出更偏向以时序(输出判断的是next_state)。(个人理解)

Desin a Moore FSM

题目:一个大型水库为多个用户供水。为了保持足够高的水位,每隔5英寸垂直放置三个传感器。
当水位高于最高传感器(S3)时,输入流速应为零。
当水位低于最低传感器(S1)时,流速应为最大值(标称流量阀和补充流量阀均打开)。
水位位于上部和下部传感器之间时的流速由两个因素决定:
水位和最后一个传感器变化之前的水位。每个水位都有一个与其相关的标称流速,如下表所示。
如果传感器变化表明之前的液位【低于】当前液位,则应出现【标称流量】。
如果之前的水位(state)高于当前水位(next_state),则应通过打开【补充流量阀】(由△FR控制)来增加流速。
绘制水库控制器的摩尔模型状态图。清楚地指示每个状态的所有状态转换和输出。FSM的输入为S1,S2和S3;输出为FR1, FR2,FR3和△FR。

在这里插入图片描述
还包括主动高同步重置,将状态机重置为相当于水位长时间处于低位时的状态(未断言传感器,且所有四个输出均已断言)。

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    parameter L1=4'b0001,//below s1
    		  S1_2=4'b0010,//between s1~s2
    		  S2_3=4'b0100,//between s2~s3
    		  H3=4'b1000;//above s3
    
    reg [3:0]state,next_state;
    reg [2:0]fr;
    
    assign {fr3,fr2,fr1}=fr;
    
    always@(posedge clk)begin
        if(reset)begin
            state<=L1;
        end
        else begin
            state<=next_state;
        end
    end
    
    always@(*)begin
        case(s)
            3'b000:next_state=L1;
            3'b001:next_state=S1_2;
            3'b011:next_state=S2_3;
            3'b111:next_state=H3;
            default:next_state=L1;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)begin
           fr<=3'b111; 
        end else begin
            case(next_state)
                L1:fr<=3'b111;
                S1_2:fr<=3'b011;
                S2_3:fr<=3'b001;
                H3:fr<=3'b000;
                default:fr<=3'b111;
            endcase
        end
    end
    
      always@(posedge clk)begin
        if(reset)begin
           dfr<=1'b1; 
        end else begin
            if(state>next_state)begin
                dfr<=1'b1;
            end
            else if(state<next_state)begin
               dfr<=1'b0; 
            end
            else
                dfr<=dfr;
        end
    end

endmodule

Lemming1

旅鼠游戏涉及大脑相当简单的小动物。非常简单,我们将使用有限状态机对其进行建模。
在旅鼠的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@(posedge clk or posedge areset)begin
        if(areset)begin
            state <= LEFT;
        end
        else begin
            state <= next_state;
        end
    end
 
    always @(*) begin
        case(state)
            LEFT:begin
                if(bump_left)begin
                    next_state = RIGHT;
                end
                else begin
                    next_state = LEFT;
                end
            end
            RIGHT:begin
                if(bump_right)begin
                    next_state = LEFT;
                end
                else begin
                    next_state = RIGHT;
                end
            end
        endcase
    end
 
    // Output logic
    assign walk_left = (state == LEFT);
    assign walk_right = (state == RIGHT);
 
endmodule

Lemming2

除了左右行走外,旅鼠还会摔倒(大概还会“啊!”)
如果地面消失在他们下面。除了在颠簸时左右行走和改变方向外,
当地面=0时,旅鼠还会摔倒并说“啊!”。
当地面再次出现(地面=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=4'b0001,RIGHT=4'b0010,DOWN_LEFT=4'b0100,DOWN_RIGHT=4'b1000;
    reg [3:0]state,next_state;
    always@(posedge clk,posedge areset)begin
        if(areset)
            state<=LEFT;
        else
            state<=next_state;
    end
    
    always@(*)begin
        case(state)
            LEFT:next_state=ground?(bump_left?RIGHT:LEFT):DOWN_LEFT;
            RIGHT:next_state=ground?(bump_right?LEFT:RIGHT):DOWN_RIGHT;
            DOWN_LEFT:next_state=ground?LEFT:DOWN_LEFT;
            DOWN_RIGHT:next_state=ground?RIGHT:DOWN_RIGHT;
            default:next_state=LEFT; 
        endcase
    end
    
    assign walk_left=(state==LEFT);
    assign walk_right=(state==RIGHT);
    assign aaah=(state==DOWN_LEFT||state==DOWN_RIGHT  
   
endmodule



Lemmings 3

除了行走和摔倒之外,有时还可以告诉旅鼠做一些有用的事情,比如挖掘(当挖掘=1时开始挖掘)。如果旅鼠当前正在地面上行走(地面=1且未坠落),【它可以挖掘,并将继续挖掘,直到到达另一侧(地面=0)】。到那时,因为没有地面,它就会坠落(啊!),然后,一旦它再次触地,继续沿着原来的方向行走。与摔倒一样,在挖掘时被撞倒没有任何影响,当摔倒或没有地面时被告知要挖掘则被忽略。
(换句话说,行走的旅鼠可以下降、挖掘或切换方向。如果满足其中一个以上的条件,下降的优先级高于挖掘,而挖掘的优先级高于切换方向。)
扩展有限状态机来模拟这种行为。

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=6'b000001,//左走状态
    		 RIGHT=6'b000010,//右走状态
         DOWN_LEFT=6'b000100,//坠落后左状态
        DOWN_RIGHT=6'b001000,//坠落后右状态
        TODIG_LEFT=6'b010000,//挖掘后左状态
       TODIG_RIGHT=6'b100000;//挖掘后右状态
    reg [5:0]state,next_state;
    
    //第一进程(状态转移)
    always@(posedge clk,posedge areset)begin
        if(areset)
            state<=LEFT;
        else
            state<=next_state;
    end
    //第二进程(状态转移条件的判断)
    always@(*)begin
        case(state)
            LEFT:next_state=ground?(dig?TODIG_LEFT:(bump_left?RIGHT:LEFT)):DOWN_LEFT;
            RIGHT:next_state=ground?(dig?TODIG_RIGHT:(bump_right?LEFT:RIGHT)):DOWN_RIGHT;
            //当ground==1时候,此刻不需要对挖掘进行判断了,因为挖掘条件是(地面=1且未坠落)
            DOWN_LEFT:next_state=ground?(LEFT):DOWN_LEFT;
            DOWN_RIGHT:next_state=ground?(RIGHT):DOWN_RIGHT;
            //开始挖掘后会一直挖掘,直到ground=0
            TODIG_LEFT:next_state=ground?TODIG_LEFT:DOWN_LEFT;
            TODIG_RIGHT:next_state=ground?TODIG_RIGHT:DOWN_RIGHT;
            default:next_state=LEFT;
        endcase
    end
    //第三
    assign walk_left=(state==LEFT);
    assign walk_right=(state==RIGHT);
    assign aaah=(state==DOWN_LEFT|state==DOWN_RIGHT);
    assign digging=(state==TODIG_LEFT|state==TODIG_RIGHT);
    
endmodule

Lemmings

虽然旅鼠可以行走、摔倒和挖掘,但旅鼠并非无懈可击。如果旅鼠摔倒太久,然后撞到地面,它可能会飞溅。特别是,如果一只旅鼠坠落超过20个时钟周期,然后撞到地面,它将飞溅并停止行走、坠落或挖掘(所有4个输出都变为0),直到永远(或直到FSM重置)。旅鼠在落地前能落多远没有上限。旅鼠只有在触地时才会飞溅;它们不会在半空中飞溅。
扩展有限状态机来模拟这种行为。
坠落20个周期可存活:
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=7'b0000001,
		 RIGHT=7'b0000010,
     DOWM_LEFT=7'b0000100,
    DOWM_RIGHT=7'b0001000,
	  DIG_LEFT=7'b0010000,
     DIG_RIGHT=7'b0100000,
		 SPLAT=7'b1000000;

reg [6:0]state,next_state;
reg [6:0]count;
always@(posedge clk,posedge areset)begin
    if(areset)
        count<=7'd0;
    else if((next_state==DOWM_LEFT)||(next_state==DOWM_RIGHT))
        count<=count+1'b1;
    else
        count<=7'd0;
end

always@(posedge clk,posedge areset)begin
    if(areset)
    	state<=LEFT;
    else
        state<=next_state;
end

always@(*)begin
    case(state)
        LEFT:next_state=ground?(dig?DIG_LEFT:(bump_left?RIGHT:LEFT)):DOWM_LEFT;
        RIGHT:next_state=ground?(dig?DIG_RIGHT:(bump_right?LEFT:RIGHT)):DOWM_RIGHT;
        DOWM_LEFT:next_state=ground?((count>7'd20)?SPLAT:LEFT):DOWM_LEFT;
        DOWM_RIGHT:next_state=ground?((count>7'd20)?SPLAT:RIGHT):DOWM_RIGHT;
        DIG_LEFT:next_state=ground?DIG_LEFT:DOWM_LEFT;
        DIG_RIGHT:next_state=ground?DIG_RIGHT:DOWM_RIGHT;
        SPLAT:next_state=SPLAT;
        default:next_state=LEFT;
    endcase
end

	    assign walk_left=(state==LEFT);
	    assign walk_right=(state==RIGHT);
	    assign aaah=(state==DOWM_RIGHT||state==DOWM_LEFT);
	    assign digging=(state==DIG_RIGHT||state==DIG_LEFT);
endmodule
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值