HDLbits答案——FSM部分(上篇)

目录

1、Simple FSM 1(asynchronous reset)——Fsm1

2、Simple FSM 1(synchronous reset)——Fsm1s

3、Simple FSM 2(asynchronous reset)——Fsm2

4、Simple FSM 2(synchronous reset)——Fsm2s

5、simple state transitions 3——Fsm3comb

6、Simple one-hot statetransitions 3——Fsm3onehot

7、Simple FSM 3(asynchronous reset)——Fsm3

8、Simple FSM 3(synchronous reset)——Fsm3s

9、Design a Moore FSM——Exams/ece241 2013 q4

10、Lemmings1

11、Lemmings2

12、Lemmings3

13、Lemmings4


FSM这一节分为了两篇,此部分为FSM的上篇内容。

1、Simple FSM 1(asynchronous reset)——Fsm1

本部分主要是参考题目给出的图的(异步复位)有限状态机,主要目的是了解状态机的主要知识。

module top_module(
    input clk,
    input areset,    // Asynchronous reset to state B
    input in,
    output out);//  

    parameter A=1'b0, B=1'b1; 
    reg state, next_state;

    always @(*) begin    // This is a combinational always block
        // State transition logic
        case(state)
            B: begin
                if(in == 0)begin
                   next_state = A; 
                end
                else begin
                   next_state = B; 
                end
            end
            
            A:begin
                if(in == 0)begin
                   next_state = B;
                end
                else begin
                   next_state = A; 
                end
            end
        endcase
    end

    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        // State flip-flops with asynchronous reset
        if(areset)begin
           state <= B; 
        end
        else begin
           state <= next_state; 
        end
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == B);

endmodule

2、Simple FSM 1(synchronous reset)——Fsm1s

这个题目本身暗示我们用一段式来进行书写,当个人认为三段式是最方便理解且后期调试的。

// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
    input clk;
    input reset;    // Synchronous reset to state B
    input in;
    output out; 
    reg out;

    // Fill in state name declarations
    parameter B=1'b0, A=1'b1;

    reg present_state, next_state;
	
    always@(posedge clk)begin
        if(reset)begin
           present_state <= B; 
        end
        else begin
           present_state <= next_state;
        end
    end
    
    always@(*)begin
        case(present_state) 
            B:begin
                if(in == 1'b0)begin
                    next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            
            A:begin
                if(in == 0)begin
                  	next_state = B;
                end
                else begin
                    next_state = A;
                end
            end
        endcase
    end
    
    assign out = (present_state == B);
    //out输出也可以使用标准三段式
    /*
    always@(*)begin
        if(present_state == B) begin
            out = 1'b1;
        end
        else begin
            out = 1'b1;
        end
    end
	*/
    
endmodule

3、Simple FSM 2(asynchronous reset)——Fsm2

这是一个Moore 状态机

module top_module(
    input clk,
    input areset,    // Asynchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF=1'b0, ON=1'b1; 
    reg state, next_state;

    always @(*) begin
        // State transition logic
        case(state)
            OFF:begin
                if(j)begin
                   next_state = ON; 
                end
                else begin
                    next_state = OFF;
                end
            end
            
            ON:begin
                if(k)begin
                  next_state = OFF;
                end
                else begin
                  next_state = ON;
                end
            end
        endcase
    end

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

    // Output logic
    // assign out = (state == ...);
    assign out = (state == ON);

endmodule

4、Simple FSM 2(synchronous reset)——Fsm2s

module top_module(
    input clk,
    input reset,    // Synchronous reset to OFF
    input j,
    input k,
    output out); //  

    parameter OFF=1'b0, ON=1'b1; 
    reg state, next_state;

    always @(*) begin
        // State transition logic
        case(state)
            OFF:begin
                if(j)begin
                    next_state = ON;
                end
                else begin
                    next_state = OFF;
                end
            end
            ON:begin
                if(k)begin
                    next_state = OFF;
                end
                else begin
                    next_state = ON;
                end
            end
        endcase
    end

    always @(posedge clk) begin
        // State flip-flops with synchronous reset
        if(reset)begin
            state <= OFF;
        end
        else begin
           state <=  next_state;
        end
    end

    // Output logic
    // assign out = (state == ...);
    assign out = (state == ON);
endmodule

5、simple state transitions 3——Fsm3comb

此部分只需要写组合逻辑和输出逻辑部分

module top_module(
    input in,
    input [1:0] state,
    output [1:0] next_state,
    output out); //

    parameter A=2'b00, B=2'b01, C=2'b10, D=2'b11;

    // State transition logic: next_state = f(state, in)
    always@(*)begin
        case(state) 
            A:begin
                next_state = in ? B : A;
            end
            
            B:begin
                next_state = in ? B : C;
            end
            
            C:begin
                next_state = in ? D : A; 
            end
            
            D:begin
                next_state = in ? B : C;   
            end
        endcase
    end

    // Output logic:  out = f(state) for a Moore state machine
    assign out = (state == D);

endmodule

6、Simple one-hot statetransitions 3——Fsm3onehot

相关翻译:

“通过检查得出方程”是什么意思?
One-hot 状态机编码保证恰好有一个状态位为 1。这意味着可以通过仅检查一个状态位而不是所有状态位来确定状态机是否处于特定状态。通过检查状态转换图中每个状态的输入边,这导致了状态转换的简单逻辑方程。

比如上面的状态机中,状态机如何才能达到状态A?它必须使用两个传入边之一:“当前处于状态 A 且 in=0”或“当前处于状态 C 且 in = 0”。由于 one-hot 编码,用于测试“当前处于状态 A”的逻辑方程只是状态 A 的状态位。这导致状态位 A 的下一个状态的最终逻辑方程:next_state[0] =状态[0]&(~in) |状态[2]&(~in)。 one-hot 编码保证一次最多有一个子句(乘积项)是“活动的”,因此这些子句可以被 ORed 在一起。

当练习要求“通过检查”获得状态转移方程时,请使用此特定方法。法官将使用非单热输入进行测试,以确保您的逻辑方程遵循此方法,而不是对状态位的非法(非单热)组合执行其他操作(例如重置 FSM)。

虽然知道这个算法对于 RTL 级设计(逻辑合成器处理这个)不是必需的,但它说明了为什么 one-hot FSM 通常具有更简单的逻辑(以更多的状态位存储为代价),并且这个主题经常显示参加数字逻辑课程的考试。
 

module top_module(
    input in,
    input [3:0] state,
    output [3:0] next_state,
    output out); //

    parameter A=0, B=1, C=2, D=3;

    // State transition logic: Derive an equation for each state flip-flop.
    assign next_state[A] = state[0]&(~in) | state[2]&(~in);
    assign next_state[B] = state[1]&( in) | state[0]&( in) | state[3]&( in);
    assign next_state[C] = state[1]&(~in) | state[3]&(~in);
    assign next_state[D] = state[2]&( in);

    // Output logic: 
    assign out = (state[3] == 1'b1);

endmodule

7、Simple FSM 3(asynchronous reset)——Fsm3

分两种方法来完成,其中第一种方法采用前面一题的思路:采用One-Hot独热码状态机原理来编写,第二种就用最开始几道题的思路来完成,主要不同点就在于组合逻辑部分。

//方案一
module top_module(
    input clk,
    input in,
    input areset,
    output out); //
    
    reg [3:0] current_state, next_state;
    
    parameter A=0, B=1, C=2, D=3;

    // State transition logic
    assign next_state[A] = current_state[A]&~in | current_state[C]&~in ;
    assign next_state[B] = current_state[B]&in | current_state[D]&in | current_state[A]&in;
    assign next_state[C] = current_state[B]&~in | current_state[D]&~in;
    assign next_state[D] = current_state[C]&in;

    // State flip-flops with asynchronous reset
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            current_state <= 4'b0001;
        end
        else begin
            current_state <= next_state;
        end
    end

    // Output logic
    assign out = (current_state[D] == 1'b1);

endmodule
module top_module(
    input clk,
    input in,
    input areset,
    output reg out); //
    
    reg [1:0] current_state, next_state;
    
    parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;

    // State transition logic
    always@(*)begin
        case(current_state)
            A:begin
                if(in == 0)begin
                    next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            
            B:begin
                if(in == 0)begin
                    next_state = C;
                end
                else begin
                    next_state = B;
                end
            end
            
            C:begin
                if(in == 0)begin
                    next_state = A;
                end
                else begin
                    next_state = D;
                end
            end
            
            D:begin
                if(in == 0)begin
                    next_state = C;
                end
                else begin
                    next_state = B;
                end
            end
        endcase
    end

    // State flip-flops with asynchronous reset
    always@(posedge clk or posedge areset)begin
        if(areset)begin
            current_state <= A;
        end
        else begin
            current_state <= next_state;
        end
    end

    // Output logic
    always@(*)begin
        if(current_state == D)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

8、Simple FSM 3(synchronous reset)——Fsm3s

和前面差不多的,这里主要是从异步复位修改成了同步复位,只需要修改时序敏感列表中的敏感信号即可。

module top_module(
    input clk,
    input in,
    input reset,
    output reg out); //
    
    parameter A=0, B=1, C=2, D=3;
    reg [2:0] current_state, next_state;

    // State transition logic
    always@(*)begin
        case(current_state)
            A:begin
                if(in == 0)begin
                    next_state = A;
                end
                else begin
                    next_state = B;
                end
            end
            
            B:begin
                if(in == 0)begin
                    next_state = C;
                end
                else begin
                    next_state = B;
                end
            end
            
            C:begin
                if(in == 0)begin
                    next_state = A;
                end
                else begin
                    next_state = D;
                end
            end
            
            D:begin
                if(in == 0)begin
                    next_state = C;
                end
                else begin
                    next_state = B;
                end
            end
        endcase
    end

    // State flip-flops with synchronous reset
    always@(posedge clk)begin
        if(reset)begin
            current_state <= A;
        end
        else begin
            current_state <= next_state;
        end
    end

    // Output logic
    always@(*)begin
        if(current_state == D)begin
            out = 1'b1;
        end
        else begin
            out = 1'b0;
        end
    end

endmodule

9、Design a Moore FSM——Exams/ece241 2013 q4

此篇主要就是偏实际应用的了,着重搞清楚这一篇的思路:如何划分出多少个状态,各个状态之间是怎么进行转换的。

这道题目根据题意,水管的3个探测器的电平变化相当于输入信号,可以分出6个状态出来,分别为:

  • 没有任何水的状态A
  • 中间状态B1,B2,C1,C2(B1、C1对应没有开额外补水阀的情况,即从低水位加到高水位进入的状态,而B2、C2为需要开额外补水阀的状态,即从高水位降到低水位的状态
  • 满水状态D
module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output reg fr3,
    output reg fr2,
    output reg fr1,
    output reg dfr
); 
    
    parameter A=3'd0, B1=3'd1, B2=3'd2, C1=3'd3, C2=3'd4, D=3'd5;
    
    reg [2:0] current_state, next_state;
    
    always@(*)begin
        case(current_state)
            A:next_state = s[1] ? B1 : A;
            B1:next_state = s[2] ? C1 : (s[1] ? B1 : A);
            C1:next_state = s[3] ? D  : (s[2] ? C1 : B2);
            D:next_state = s[3] ? D  : C2;
            C2:next_state = s[3] ? D : (s[2] ? C2 : B2);
            B2:next_state = s[2] ? C1 : (s[1] ? B2 : A);
            default: next_state = 'x;
        endcase
    end
    
    always@(posedge clk)begin
        if(reset)begin
           current_state <= A; 
        end
        else begin
           current_state <= next_state; 
        end
    end
    
    always@(*)begin
        case(current_state) 
            A: {fr3, fr2, fr1, dfr} = 4'b1111;
            B1: {fr3, fr2, fr1, dfr} = 4'b0110;
            B2: {fr3, fr2, fr1, dfr} = 4'b0111;
            C1: {fr3, fr2, fr1, dfr} = 4'b0010;
            C2: {fr3, fr2, fr1, dfr} = 4'b0011;
            D: {fr3, fr2, fr1, dfr} = 4'b0000;
            default: {fr3, fr2, fr1, dfr} = 'x;
        endcase
    end

endmodule

10、Lemmings1

此部分将进入一个逐步递进试的题目,主要对象是写一个旅鼠游戏,详情可以看题目,这个部分的内容有很强的递进逻辑思维,后面的题目需要前面题目的基础上增加一些逻辑,逐步完善成一个游戏。

本题是一个旅鼠游戏,就是像自动小车一样,假设有两个车道,小车只能处于其中一个车道,当小车在此车道遇到障碍物时,就会选择另外一个车道继续行驶

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=0, RIGHT=1, ...
    parameter left = 0, right = 1;
    
    reg state, next_state;

    always @(*) begin
        // State transition logic
        case(state)
            left: next_state = bump_left ? right : left;
            right:next_state = bump_right? left  : right;
            default next_state = 'x;
        endcase
    end

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

    assign walk_left = (state == left);
    assign walk_right = (state == right);
    // Output logic
    // assign walk_left = (state == ...);
    // assign walk_right = (state == ...);

endmodule

11、Lemmings2

此题目为第一题的递进版本,引入了上下空间的元素,从状态机上来看就相当于新引入了两个状态。此处逻辑和上一题是一样的,此题在组合逻辑部分采用了与上一题不同的方式进行编写。

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 ); 
    
    //状态定义,定义4个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落
    parameter left = 2'd0, right = 2'd1, fall_left = 2'd2, fall_right = 2'd3;
    
    reg [1:0] state, next_state;
    
    always@(*)begin
        case(state)
            left:next_state = ground ? (bump_left ? right : left) : fall_left;
            
            right:next_state = ground ? (bump_right ? left : right) : fall_right;
            
            fall_left:next_state = ground ? left : fall_left;
            
            fall_right:next_state = ground ? right : fall_right;
            
            default: next_state = 'x;
        endcase
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
           state <= left; 
        end
        else begin
           state <= next_state; 
        end
    end
    
    assign walk_left = (state == left);
    assign walk_right = (state == right);
    assign aaah = (state == fall_left) || (state == fall_right);
    

endmodule

12、Lemmings3

本题就是同理在第二道题目的基础上加入了挖掘的动作。

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 ); 
    
    
    //状态定义,定义4个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落
    parameter left = 3'd0, right = 3'd1, fall_left = 3'd2, fall_right = 3'd3, dig_left = 3'd4, dig_right = 3'd5;
    
    reg [2:0] state, next_state;
    
    always@(*)begin
        case(state)
            left:next_state = ground ? (dig ? dig_left : (bump_left ? right : left)) : fall_left;
            
            right:next_state = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
            
            fall_left:next_state = ground ? left : fall_left;
            
            fall_right:next_state = ground ? right : fall_right;
            
            dig_left:next_state = ground ? dig_left : fall_left;
            
            dig_right:next_state = ground ? dig_right : fall_right;
            
            default: next_state = 'x;
        endcase
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
           state <= left; 
        end
        else begin
           state <= next_state; 
        end
    end
    
    assign walk_left = (state == left);
    assign walk_right = (state == right);
    assign aaah = (state == fall_left) || (state == fall_right);
    assign digging = (state == dig_left) || (state == dig_right);
    

endmodule

13、Lemmings4

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 ); 
    
  
    //状态定义,定义7个状态,分别为:1、向左走, 2、像右走,3、左走时跌落,4、右走时跌落,5、挖掘_左走状态,挖掘_右走状态,6、摔了(splatter)
    parameter left = 3'd0, right = 3'd1, fall_left = 3'd2, fall_right = 3'd3, dig_left = 3'd4, dig_right = 3'd5, splatter = 3'd6;
    
    reg [2:0] state, next_state;
    //integer cnt;			//使用integer型就可以编译成功
    reg [31:0] cnt;  //此处我使用了reg型变量作为寄存器就编译不成功 
    //-> 已解决主要本人在此处定的reg型变量cnt的位宽不够,在短时间内可以满足fall计时任务
    //但是如果超出了计时寄存器的位宽的话就会出现错误
    
    always@(*)begin
        case(state)
            left:next_state = ground ? (dig ? dig_left : (bump_left ? right : left)) : fall_left;
            
            right:next_state = ground ? (dig ? dig_right : (bump_right ? left : right)) : fall_right;
            
            //前面部分进行判断,因此本题可以有两种方案:1:在落地的时候进行状态变换;2:在落地前进行状态变换。
            fall_left:next_state = ground ? ((cnt > 32'd19) ? splatter : left) : fall_left;
            
            fall_right:next_state = ground ? ((cnt > 32'd19) ? splatter : right) : fall_right;
            
            dig_left:next_state = ground ? dig_left : fall_left;
            
            dig_right:next_state = ground ? dig_right : fall_right;
            
            splatter:next_state = splatter;
            
            default: next_state = left;
        endcase
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin
           state <= left;
        end
        else begin
           state <= next_state; 
        end
    end
    
    always@(posedge clk or posedge areset)begin
        if(areset)begin 
           cnt <= 32'd0; 
        end
        //此处需要用 '||(逻辑或)'逻辑操作符,之前没注意,便使用的为 '|(或)'按位操作符 
        //此处没什么影响,但需要形成良好习惯
        else if(state == fall_left || state == fall_right)begin		
           cnt <= cnt + 1'd1; 
        end
        else begin
           cnt <= 32'd0; 
        end
        
    end

    
    assign walk_left = (state == left);
    assign walk_right = (state == right);
    assign aaah = (state == fall_left) || (state == fall_right);
    assign digging = (state == dig_left) || (state == dig_right);
    

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小竹笙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值