目录

  1. 状态机概述
  2. 状态机的类型
  3. Verilog 状态机设计方法
  4. 状态机编码方式
  5. Verilog 状态机示例
  6. 参考资料

状态机概述

在数字设计中,状态机(Finite State Machine, FSM)是一种常用的建模工具,用于描述系统随时间变化的状态和状态之间的转移。状态机通过根据输入信号、当前状态以及设计逻辑来确定下一状态,常用于控制系统、数据传输协议、计数器、时序逻辑等应用。

状态机的基本要素:

  • 状态:表示系统在某一时刻的特定情况。
  • 输入:影响系统状态转移的外部信号。
  • 状态转移:根据输入和当前状态,系统从一个状态跳转到另一个状态。
  • 输出:系统在某一状态下的行为,通常由当前状态和输入共同决定。

状态机通常分为两类:

  1. Mealy 状态机:输出依赖于当前状态和输入。
  2. Moore 状态机:输出仅依赖于当前状态。

状态机的类型

1. Mealy 状态机

在 Mealy 状态机中,输出不仅依赖于当前状态,还依赖于当前输入。也就是说,输出是状态和输入的函数。

  • 优点:响应更快,输出可以更细粒度地依赖输入。
  • 缺点:设计较复杂,输出的变化可能会导致不必要的波动。

2. Moore 状态机

在 Moore 状态机中,输出仅依赖于当前状态,而不受输入的影响。也就是说,输出是状态的函数。

  • 优点:设计更简单,输出仅取决于状态,避免了 Mealy 状态机中输出随输入变化的复杂性。
  • 缺点:响应较慢,可能会引入冗余的输出变化。

Verilog 状态机设计方法

设计状态机时,一般按照以下步骤进行:

  1. 确定状态:明确系统的所有可能状态。
  2. 绘制状态图:使用状态图表示状态之间的转移,并标明状态转移条件。
  3. 编码状态:为每个状态分配一个唯一的二进制值。
  4. 设计状态转移逻辑:根据输入信号和当前状态,设计状态转移的条件和输出。
  5. 实现状态机:使用 Verilog 编写状态机的代码。

状态机编码方式

状态机的实现可以通过不同的编码方式来完成。常见的编码方式有:

  1. 二进制编码:使用最小数量的位来表示状态。
  2. 格雷编码:通过减少相邻状态之间的位差来简化状态转移。
  3. 热编码:每个状态使用不同的位来表示,每个位都有不同的状态。

二进制编码

对于 3 个状态,可以用 2 位二进制编码表示 4 个状态(2^2),如:

  • 状态 0:00
  • 状态 1:01
  • 状态 2:10

这种方式是最常用的。

状态转移与输出逻辑

在设计状态机时,状态转移逻辑可以通过 case 语句来实现,输出逻辑也通常在 case 语句中进行定义。


Verilog 状态机示例

示例 1:Mealy 状态机示例

假设我们设计一个简单的 Mealy 状态机,检测一个输入信号的“101”模式。即,当输入信号为 1、0、1 时,状态机输出为 1。

module mealy_fsm(
    input clk,
    input reset,
    input in,       // 输入信号
    output reg out  // 输出信号
);

    // 状态编码
    typedef enum reg [1:0] {
        S0 = 2'b00,  // 初始状态
        S1 = 2'b01,  // 状态 1
        S2 = 2'b10   // 状态 2
    } state_t;

    // 当前状态和下一个状态
    state_t current_state, next_state;

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

    // 状态转移和输出逻辑
    always @(current_state or in) begin
        case (current_state)
            S0: begin
                if (in) next_state = S1; // 输入为 1,跳转到 S1
                else next_state = S0;    // 输入为 0,保持在 S0
                out = 0;                  // 默认输出为 0
            end
            S1: begin
                if (in) next_state = S1; // 输入为 1,保持在 S1
                else next_state = S2;    // 输入为 0,跳转到 S2
                out = 0;                  // 默认输出为 0
            end
            S2: begin
                if (in) next_state = S1; // 输入为 1,跳转回 S1
                else next_state = S0;    // 输入为 0,返回 S0
                out = 1;                  // 检测到 101 模式,输出 1
            end
            default: begin
                next_state = S0;
                out = 0;
            end
        endcase
    end
endmodule

在这个例子中,Mealy 状态机有三个状态:

  • S0:初始状态。
  • S1:已接收到第一个 1。
  • S2:已接收到 10。
  • 当输入信号为 1、0、1 时,状态机输出 1。

示例 2:Moore 状态机示例

假设我们设计一个 Moore 状态机,功能是检测输入信号的“101”模式,且只有在完成模式检测后才输出 1。

module moore_fsm(
    input clk,
    input reset,
    input in,       // 输入信号
    output reg out  // 输出信号
);

    // 状态编码
    typedef enum reg [1:0] {
        S0 = 2'b00,  // 初始状态
        S1 = 2'b01,  // 状态 1
        S2 = 2'b10   // 状态 2
    } state_t;

    // 当前状态和下一个状态
    state_t current_state, next_state;

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

    // 状态转移逻辑
    always @(current_state or in) begin
        case (current_state)
            S0: begin
                if (in) next_state = S1; // 输入为 1,跳转到 S1
                else next_state = S0;    // 输入为 0,保持在 S0
            end
            S1: begin
                if (in) next_state = S1; // 输入为 1,保持在 S1
                else next_state = S2;    // 输入为 0,跳转到 S2
            end
            S2: begin
                if (in) next_state = S1; // 输入为 1,跳转回 S1
                else next_state = S0;    // 输入为 0,返回 S0
            end
            default: next_state = S0;
        endcase
    end

    // 输出逻辑:仅在状态 S2 时输出 1
    always @(current_state) begin
        if (current_state == S2)
            out = 1;  // 完成模式检测,输出 1
        else
            out = 0;  // 默认输出为 0
    end
endmodule

在这个 Moore 状态机中,状态机有三个状态:

  • S0:初始状态。
  • S1:已接收到第一个 1。
  • S2:已接收到 10,并且在此时输出 1。

参考资料