【HDLbits--FSM状态机】

HDLbits--FSM状态机

    • 1.6 FSM 介绍
    • 1.6 FSM 示例
      • 1 单输入单输出FSM
      • 2 双输入单输出FSM
      • 3 真指标状态
      • 4 Moore FSM demo
      • 5 时序图和状态图写状态机

【博客首发于微信公众号《漫谈芯片与编程》,欢迎大家关注,多谢大家】

1.6 FSM 介绍

在Verilog中,有限状态机(Finite State Machine, FSM)是一种用于描述系统行为的模型,通常用于控制逻辑的设计。FSM由一组状态、状态之间的转换条件以及每个状态下的输出组成。
FSM可以分为两种类型:

  • Moore型状态机:输出仅依赖于当前状态。
  • Mealy型状态机:输出依赖于当前状态和输入。

FSM的基本组成部分:

  • 状态寄存器(State Register):用于存储当前状态。
  • 状态转移逻辑(Next State Logic):根据当前状态和输入信号,决定下一个状态。
  • 输出逻辑(Output Logic):根据当前状态(Moore型)或当前状态和输入(Mealy型)生成输出信号。

Verilog实现FSM的步骤:

  • 定义状态:通常使用parameter或typedef来定义状态。
  • 状态寄存器:使用reg或logic声明状态寄存器。
  • 状态转移逻辑:使用always块描述状态转移。
  • 输出逻辑:使用assign或always块描述输出。

示例:简单的Moore型FSM
假设我们要设计一个简单的FSM,它有三个状态:IDLE、STATE1、STATE2,并且根据输入信号input_signal进行状态转移。

module moore_fsm (
    input wire clk,
    input wire reset,
    input wire input_signal,
    output reg output_signal
);

    // 定义状态
    typedef enum reg [1:0] {
        IDLE  = 2'b00,
        STATE1 = 2'b01,
        STATE2 = 2'b10
    } state_t;

    // 状态寄存器和下一个状态变量
    state_t current_state, next_state;

    // 状态转移逻辑
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
        end else begin
            current_state <= next_state;
        end
    end

    // 下一个状态逻辑
    always @(*) begin
        case (current_state)
            IDLE: begin
                if (input_signal) begin
                    next_state = STATE1;
                end else begin
                    next_state = IDLE;
                end
            end
            STATE1: begin
                if (input_signal) begin
                    next_state = STATE2;
                end else begin
                    next_state = IDLE;
                end
            end
            STATE2: begin
                if (input_signal) begin
                    next_state = IDLE;
                end else begin
                    next_state = STATE2;
                end
            end
            default: begin
                next_state = IDLE;
            end
        endcase
    end

    // 输出逻辑 (Moore型)
    always @(*) begin
        case (current_state)
            IDLE:   output_signal = 1'b0;
            STATE1: output_signal = 1'b1;
            STATE2: output_signal = 1'b0;
            default: output_signal = 1'b0;
        endcase
    end

endmodule

示例:简单的Mealy型FSM
在Mealy型FSM中,输出不仅依赖于当前状态,还依赖于输入信号。

module mealy_fsm (
    input wire clk,
    input wire reset,
    input wire input_signal,
    output reg output_signal
);

    // 定义状态
    typedef enum reg [1:0] {
        IDLE  = 2'b00,
        STATE1 = 2'b01,
        STATE2 = 2'b10
    } state_t;

    // 状态寄存器和下一个状态变量
    state_t current_state, next_state;

    // 状态转移逻辑
    always @(posedge clk or posedge reset) begin
        if (reset) begin
            current_state <= IDLE;
        end else begin
            current_state <= next_state;
        end
    end

    // 下一个状态逻辑
    always @(*) begin
        case (current_state)
            IDLE: begin
                if (input_signal) begin
                    next_state = STATE1;
                end else begin
                    next_state = IDLE;
                end
            end
            STATE1: begin
                if (input_signal) begin
                    next_state = STATE2;
                end else begin
                    next_state = IDLE;
                end
            end
            STATE2: begin
                if (input_signal) begin
                    next_state = IDLE;
                end else begin
                    next_state = STATE2;
                end
            end
            default: begin
                next_state = IDLE;
            end
        endcase
    end

    // 输出逻辑 (Mealy型)
    always @(*) begin
        case (current_state)
            IDLE:   output_signal = 1'b0;
            STATE1: output_signal = input_signal ? 1'b1 : 1'b0;
            STATE2: output_signal = input_signal ? 1'b0 : 1'b1;
            default: output_signal = 1'b0;
        endcase
    end

endmodule

总结
Moore型FSM:输出仅依赖于当前状态。
Mealy型FSM:输出依赖于当前状态和输入信号。
在Verilog中,FSM的实现通常包括状态定义、状态寄存器、状态转移逻辑和输出逻辑。
通过合理设计FSM,可以实现复杂的控制逻辑,适用于各种数字电路设计场景。

1.6 FSM 示例

1 单输入单输出FSM

【HDLbits--FSM状态机】_第1张图片

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

    parameter A=0, B=1; 
    reg state, next_state;

    always @(*) begin    // This is a combinational always block
        if(areset) begin
           next_state = B; 
        end else begin
            case(state)
                A: next_state = (in==1'b1) ? A : B;
                B: next_state = (in==1'b1) ? B : A;
                default:  ;
            endcase
        end
    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 双输入单输出FSM

【HDLbits--FSM状态机】_第2张图片


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

    parameter OFF=0, ON=1; 
    reg state, next_state;

    always @(*) begin
        // State transition logic
        if(areset) begin
            next_state = OFF;
        end
        case(state)
            OFF: begin
                next_state =  (j==1'b1) ? ON :OFF;
            end
            
            ON: begin
                next_state = (k==1'b1) ? OFF : ON;
            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


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

    parameter OFF=0, ON=1; 
    reg state, next_state;

    always @(*) begin
        // State transition logic
        if(reset) begin
            next_state = OFF;
        end
        case(state)
            OFF: begin
                next_state =  (j==1'b1) ? ON :OFF;
            end
            
            ON: begin
                next_state = (k==1'b1) ? OFF : ON;
            end
                
        endcase
    end

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

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

endmodule

3 真指标状态

仅实现该状态机的状态转换逻辑和输出逻辑(组合逻辑部分)。 给定当前状态(state),根据状态转换表计算next_state和输出(out)。
【HDLbits--FSM状态机】_第3张图片

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

    parameter A=0, B=1, C=2, D=3;
	
    // State transition logic: next_state = f(state, in)
    always @(*) begin
        case(state) 
            A: next_state = (in==1'b0) ? A : B;
            B: next_state = (in==1'b0) ? C : B;
            C: next_state = (in==1'b0) ? A : D;
            D: next_state = (in==1'b0) ? C : B;
        endcase
    end
    // Output logic:  out = f(state) for a Moore state machine
	
    always @(*) begin
        case(state) 
            A : out = 1'b0;
           	B : out = 1'b0;
            C : out = 1'b0;
            D : out = 1'b1;
        endcase
    end
    
endmodule

//=====
module top_module(
    input clk,
    input in,
    input areset,
    output out); //

    parameter A = 4'b0001;
    parameter B = 4'b0010;
    parameter C = 4'b0100;
    parameter D = 4'b1000;
    
    reg[4 -1:0] cur_sta;
    reg[4 -1:0] nxt_sta;
    // State transition logic
    always @(*) begin
        if(areset) begin
           nxt_sta = A; 
        end else begin
            case(cur_sta)
                A: nxt_sta = (in==0) ? A : B;
                B: nxt_sta = (in==0) ? C : B;
                C: nxt_sta = (in==0) ? A : D;
                D: nxt_sta = (in==0) ? C : B;
                default: 	;
            endcase
        end
    end
    // State flip-flops with asynchronous reset
    always @(posedge clk or posedge areset) begin
        if(areset) begin
            cur_sta <= A;
        end else begin
           cur_sta <= nxt_sta; 
        end
    end
    // Output logic
    assign out = (cur_sta==D);
endmodule

4 Moore FSM demo

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output reg fr3,
    output reg fr2,
    output reg fr1,
    output reg dfr
);


    parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
    reg [2:0] state, next;      // Make sure these are big enough to hold the state encodings.

    // Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.    
    always @(posedge clk) begin
        if (reset) state <= A2;
        else state <= next;
    end

    // Combinational always block for state transition logic. Given the current state and inputs,
    // what should be next state be?
    // Combinational always block: Use blocking assignments.    
    always@(*) begin
        case (state)
            A2: next = s[1] ? B1 : A2;
            B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
            B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
            C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
            C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
            D1: next = s[3] ? D1 : C2;
            default: next = 'x;
        endcase
    end


    // Combinational output logic. In this problem, a procedural block (combinational always block) 
    // is more convenient. Be careful not to create a latch.
    always@(*) begin
        case (state)
            A2: {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;
            D1: {fr3, fr2, fr1, dfr} = 4'b0000;
            default: {fr3, fr2, fr1, dfr} = 'x;
        endcase
    end

endmodule

5 时序图和状态图写状态机

【HDLbits--FSM状态机】_第4张图片


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 WALK_LEFT = 4'b0001;
    parameter WALK_RIGHT= 4'b0010;
    parameter FALL_LEFT = 4'b0100;
    parameter FALL_RIGHT= 4'b1000;
    
    reg[3:0] cur_sta;
    reg[3:0] nxt_sta;
    
    always @(posedge clk or posedge areset) begin
        if(areset) begin
            cur_sta <= WALK_LEFT;
        end else begin
           cur_sta <= nxt_sta; 
        end
    end
    
    always @(*) begin
        if(areset) begin
            nxt_sta = WALK_LEFT;
        end else begin
            case(cur_sta)
                WALK_LEFT: begin
                    if(~ground) begin
                       nxt_sta = FALL_LEFT; 
                    end else begin
                        if(bump_left) begin
                            nxt_sta = WALK_RIGHT;
                        end else begin
                            nxt_sta = WALK_LEFT; 
                        end
                    end
                end
                
                WALK_RIGHT: begin
                    if(~ground) begin
                        nxt_sta = FALL_RIGHT;
                    end else begin
                        if(bump_right) begin
                            nxt_sta = WALK_LEFT;
                        end else begin
                           nxt_sta = WALK_RIGHT;
                        end
                    end
                end
                
                FALL_LEFT: begin
                    if(ground) begin
                       nxt_sta = WALK_LEFT; 
                    end else begin
                       nxt_sta = FALL_LEFT;
                    end
                end
                
                FALL_RIGHT: begin
                    if(ground) begin
                        nxt_sta = WALK_RIGHT;
                    end else begin
                       nxt_sta = FALL_RIGHT;
                    end
                end
            endcase
        end
    end
    
    always @(*) begin
        walk_left = 0;
    	walk_right= 0;
    	aaah	  = 0;
        case(cur_sta) 
            WALK_LEFT: walk_left = 1'b1;
            WALK_RIGHT:walk_right= 1'b1;
            FALL_LEFT: aaah = 1'b1;
            FALL_RIGHT:aaah = 1'b1;
        endcase
    end
    
endmodule

你可能感兴趣的:(HDL,HDL)