一、Verilog状态机编码方式概述

在Verilog里,状态机是一种非常实用的设计方法,它可以用有限个状态来描述一个复杂的逻辑过程。就好比我们做一件事情,会有不同的步骤,每个步骤就是一个状态,状态机就是按照一定的规则在这些状态之间转换。而状态机的编码方式,就相当于给每个状态起了一个独一无二的“名字”,常用的有格雷码、独热码和二进制码。那不同的编码方式对Verilog综合面积和时序收敛会有什么影响呢?我们下面就来详细说说。

1.1 二进制码

二进制码是最常见的一种编码方式,它就像我们平时用的数字一样,用二进制数来表示每个状态。比如有4个状态,我们可以用00、01、10、11来表示。这种编码方式的优点是很节省编码位宽,只需要log2(n)位就可以表示n个状态。

下面是一个简单的Verilog示例,使用二进制码实现一个4状态的状态机:


module binary_fsm (
    input wire clk,      // 时钟信号
    input wire rst_n,    // 异步复位信号,低电平有效
    output reg [1:0] state  // 2位二进制状态输出
);

// 状态定义
localparam STATE_0 = 2'b00;
localparam STATE_1 = 2'b01;
localparam STATE_2 = 2'b10;
localparam STATE_3 = 2'b11;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= STATE_0;  // 复位时进入状态0
    end else begin
        case (state)
            STATE_0: state <= STATE_1;  // 状态0转移到状态1
            STATE_1: state <= STATE_2;  // 状态1转移到状态2
            STATE_2: state <= STATE_3;  // 状态2转移到状态3
            STATE_3: state <= STATE_0;  // 状态3转移到状态0
            default: state <= STATE_0;  // 默认回到状态0
        endcase
    end
end

endmodule

1.2 格雷码

格雷码和二进制码有点像,但它有个特点,就是相邻的两个编码之间只有一位不同。比如00到01,01到11,11到10。这样在状态转换的时候,就可以减少竞争和冒险,提高时序收敛的性能。

下面是一个用格雷码实现4状态状态机的示例:


module gray_fsm (
    input wire clk,      // 时钟信号
    input wire rst_n,    // 异步复位信号,低电平有效
    output reg [1:0] state  // 2位格雷码状态输出
);

// 格雷码状态定义
localparam GRAY_0 = 2'b00;
localparam GRAY_1 = 2'b01;
localparam GRAY_2 = 2'b11;
localparam GRAY_3 = 2'b10;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= GRAY_0;  // 复位时进入状态0
    end else begin
        case (state)
            GRAY_0: state <= GRAY_1;  // 状态0转移到状态1
            GRAY_1: state <= GRAY_2;  // 状态1转移到状态2
            GRAY_2: state <= GRAY_3;  // 状态2转移到状态3
            GRAY_3: state <= GRAY_0;  // 状态3转移到状态0
            default: state <= GRAY_0;  // 默认回到状态0
        endcase
    end
end

endmodule

1.3 独热码

独热码就是每个状态都用一个单独的位来表示,只有一位是1,其他位都是0。比如有4个状态,就用0001、0010、0100、1000来表示。这种编码方式的优点是状态译码简单,速度快,但是会占用比较多的编码位宽。

下面是一个用独热码实现4状态状态机的示例:


module one_hot_fsm (
    input wire clk,      // 时钟信号
    input wire rst_n,    // 异步复位信号,低电平有效
    output reg [3:0] state  // 4位独热码状态输出
);

// 独热码状态定义
localparam ONE_HOT_0 = 4'b0001;
localparam ONE_HOT_1 = 4'b0010;
localparam ONE_HOT_2 = 4'b0100;
localparam ONE_HOT_3 = 4'b1000;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        state <= ONE_HOT_0;  // 复位时进入状态0
    end else begin
        case (state)
            ONE_HOT_0: state <= ONE_HOT_1;  // 状态0转移到状态1
            ONE_HOT_1: state <= ONE_HOT_2;  // 状态1转移到状态2
            ONE_HOT_2: state <= ONE_HOT_3;  // 状态2转移到状态3
            ONE_HOT_3: state <= ONE_HOT_0;  // 状态3转移到状态0
            default: state <= ONE_HOT_0;  // 默认回到状态0
        endcase
    end
end

endmodule

二、对综合面积的影响

2.1 二进制码的综合面积

二进制码编码位宽小,这就意味着在实现状态机的时候,需要的触发器数量少。因为触发器在数字电路里是要占面积的,所以二进制码在面积上有优势。比如上面的4状态状态机,只需要2个触发器就可以实现。但是在状态译码的时候,可能需要比较复杂的组合逻辑,这部分逻辑会占用一定的面积。

2.2 格雷码的综合面积

格雷码和二进制码的编码位宽是一样的,所以触发器的数量也相同。但是格雷码在状态转换时减少了竞争和冒险,可能会让组合逻辑部分稍微简单一些,不过总体来说,和二进制码在综合面积上差别不是很大。

2.3 独热码的综合面积

独热码每个状态都用一个单独的位来表示,所以需要的触发器数量和状态数是一样的。比如4状态状态机就需要4个触发器,这就比二进制码和格雷码需要的触发器多,所以在面积上会比较大。但是独热码的状态译码非常简单,组合逻辑部分占用的面积小。

三、对时序收敛的影响

3.1 二进制码的时序收敛

二进制码在状态转换时,可能会有多位同时变化的情况,这就会产生竞争和冒险,影响时序收敛。比如从01到10,有两位同时变化,可能会导致信号传输延迟不一致,出现毛刺。

3.2 格雷码的时序收敛

格雷码相邻状态只有一位不同,在状态转换时不会出现多位同时变化的情况,大大减少了竞争和冒险,所以在时序收敛方面表现比较好。比如从00到01,只有一位变化,信号传输比较稳定。

3.3 独热码的时序收敛

独热码状态译码简单,状态转换速度快,时序路径短,所以在时序收敛方面也有很好的表现。而且它不会出现多位同时变化的问题,避免了竞争和冒险。

四、工程权衡分析

4.1 应用场景

  • 二进制码:适用于状态数比较多的情况,因为它可以用较少的位宽表示很多状态,节省硬件资源。比如一个有16个状态的状态机,用二进制码只需要4位就可以表示。像一些简单的计数器、序列检测器等可以用二进制码来实现。
  • 格雷码:适用于对时序要求比较高,状态转换频繁的场景。比如在高速数据采集系统中,状态机需要快速准确地转换状态,格雷码就很合适。
  • 独热码:适用于状态数较少,对译码速度要求高的场景。比如一些控制电路,状态机的状态数不多,但是需要快速地进行状态判断和转换,独热码就可以发挥它的优势。

4.2 技术优缺点

  • 二进制码
    • 优点:编码位宽小,节省触发器资源,适合状态数多的情况。
    • 缺点:状态转换可能产生竞争和冒险,影响时序收敛;状态译码可能需要复杂的组合逻辑。
  • 格雷码
    • 优点:相邻状态只有一位变化,减少竞争和冒险,时序收敛性能好。
    • 缺点:编码和译码相对二进制码稍微复杂一些。
  • 独热码
    • 优点:状态译码简单,速度快,时序路径短,时序收敛性能好。
    • 缺点:需要的触发器数量多,占用硬件资源大,不适合状态数多的情况。

4.3 注意事项

  • 在选择编码方式时,要根据具体的设计需求和硬件资源来决定。如果硬件资源有限,状态数多,时序要求不是特别高,可以选择二进制码;如果对时序要求高,状态转换频繁,就考虑格雷码;如果状态数少,对译码速度要求高,就用独热码。
  • 在使用独热码时,要注意硬件资源的使用情况,避免资源浪费。
  • 在设计状态机时,要进行充分的仿真和验证,确保状态机的功能和时序都符合要求。

五、文章总结

不同的状态机编码方式在Verilog综合面积和时序收敛方面各有优劣。二进制码节省编码位宽,但可能会有竞争和冒险问题;格雷码减少了竞争和冒险,时序收敛性能好;独热码状态译码简单,速度快,但占用硬件资源多。在工程实践中,我们要根据具体的应用场景、技术优缺点和注意事项来权衡选择合适的编码方式,以达到最优的设计效果。