FPGA设计两段与三段状态机分析

状态机的基本概念

1) 摩尔型 和 米莉型状态机都是有限状态机( FSM );
2) 摩尔型状态机:时序电路的输出只取决于当前状态;
3) 米莉型状态机:时序电路的输出不但取决于状态还取决于输入;
4) 对于FPGA设计实现的有限状态机,建议使用独热码,因为虽然独热编码多用了连个触发器,但是所使用的的组合电路省一些,但是所使用的组合电路可省一些,因而使得电路速度和可靠性显著高,而总的单元数并无显著增加。采用独热编码后有了很多多余的状态,因此在case语句的最后一定要添加default分支项。可以使用默认项表示该项,也可以使用确定项表示该项,确保回到Idle状态。一般综合器都可以通过综合指令的控制合理地处理默认项。
5) 一般使用同步置位与复位状态机,always块的执行只由时钟跳边沿触发,是否置位 或者 复位,应该在always块中首先检查set 和 reset 信号的电平。所以set和reset饿电平维持时间必须大于时钟沿的间隔时间,否则set和reset不能每次都能有效的完成置位和复位的工作

一段式状态机

整个电路用一个always块(即一段)描述,包含状态转移条件判断、状态输出和状态寄存器转移,如下图。

image-20220826110500321

特点
一段式建模必须考虑现在何种状态转移条件下会进入哪些次态,然后在每个现态的case分支下分别描述每个次态的输出。
缺点:
1)不利于修改和维护代码;
2)不符合时序逻辑与组合逻辑分开描述的代码描述风格;
3)不利于附加约束;
4)不利于综合器 和 布局布线器对设计的优化;
5)代码冗长。

两段式状态机

image-20220826154814558

第一个进程(同步时序always模块),格式化描述次态到现态的转移;第二个进程(纯组合逻辑always模块),一般情况下是组合逻辑输出,如果时序允许,尽量寄存器输出

缺点: 使用两段式,其输出一般使用组合逻辑描述,而组合逻辑易产生毛刺等不稳定因素。

三段式状态机

image-20220826155917275

特点
只需要指定case敏感列表次态寄存器,然后在每个次态case分支中描述该状态的输出即可(根本不用考虑状态转移条件)。

三段式优点

1)FSM做到了同步寄存器输出;

2)消除了组合逻辑输出的不稳定与毛刺的隐患;

3)更利于时序路径分组;

4)在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。

代码设计举例

image-20220826160931766

针对上述状态转移图,设计状态机代码如下。

一段式状态机设计。


`timescale  1ns / 1ps

module  module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input                       sys_clk,
input                       areset,
input                       in,
output  reg                 out
);

parameter   A = 1'b0;
parameter   B = 1'b1;

// Define intermediate signal as reg --To reduce the probability of Matastable State
reg           state;

always @(posedge clk or posedge areset) begin
    if (areset) begin
        state <= B;
        out <= 1'b1;
    end

    else begin
        case( state )
            B:begin
                if( in == 1'b1 ) begin
                    state <= B;
                    out <= 1'b1;
                end

                else begin
                    state <= A;
                    out <= 1'b0;
                end
            end

            A:begin
                if( in <= 1'b1 ) begin
                   state <= A;
                   out <= 1'b0; 
                end
            end

            default:begin
                state <= B;
                out <= 1'b1;
            end

        endcase 

    end
end

endmodule

二段式状态机设计


`timescale  1ns / 1ps

module  module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input                       sys_clk,
input                       areset,
input                       in,
output  reg                 out
);

parameter   A = 1'b0;
parameter   B = 1'b1;
// Define intermediate signal as reg --To reduce the probability of Matastable State
// reg           state;
reg     current_state;
reg     next_state;

always @(posedge clk or posedge areset) begin
    if (areset) begin
        current_state <= B;
    end

    else begin
        current_state <= next_state;
    end
end

always @ (*)    begin
    case( current_state )
        B:begin
            if( in == 1'b1 )    begin
                next_state = B;
            end

            else begin
                next_state = A;
            end
            out = 1'b1;
        end

        A:begin
            out = 1'b0;
            if( in == 1'b1 )    begin
                next_state = A;
            end

            else begin
                next_state = B;
            end
            out = 1'b0;
        end
    endcase
end

endmodule

三段式状态机


`timescale  1ns / 1ps

module  module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input                       sys_clk,
input                       areset,
input                       in,
output  reg                 out
);

parameter   A = 1'b0;
parameter   B = 1'b1;

// Define intermediate signal as reg --To reduce the probability of Matastable State
// reg           state;
reg     current_state;
reg     next_state;

always @(posedge sys_clk or posedge areset) begin
    if (areset) begin
        current_state <= B;
    end

    else begin
        current_state <= next_state;
    end
end

always @ (*)    begin
    case( current_state )
        B:begin
            if( in == 1'b1 )    begin
                next_state = B;
            end

            else begin
                next_state = A;
            end
            // out = 1'b1;
        end

        A:begin
            out = 1'b0;
            if( in == 1'b1 )    begin
                next_state = A;
            end

            else begin
                next_state = B;
            end
            // out = 1'b0;
        end
    endcase
end

always @( posedge sys_clk or negedge areset )    
begin
    if ( areset )   begin
        out <= 1'b1;
    end

    else if( next_state == B ) begin
        out <= 1'b1;
    end

    else begin
        out <= 1'b0;
    end
end

endmodule

   转载规则


《FPGA设计两段与三段状态机分析》 HELLO WORLD 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
vivado中快速找到综合后schematic中object vivado中快速找到综合后schematic中object
在vivado中对设计的RTL代码进行综合后,查看schematic可以更清楚各个模块之间的连线关系。如下图所示: 打开RTL ANALYSIS 即可查看到模块级联的关系图。
2022-03-23
下一篇 
基于Gitee与TortoiseSVN的代码管理 基于Gitee与TortoiseSVN的代码管理
基础软件使用版本控制客户端软件:TortoiseSVN 发现git 无法更新内容到github,寻找原因中。 例如FPGA工程产生的空文件夹,SVN 无法commit, 可以使用批处理工具为空文件夹下添加 .keep文件。批处理文件链接如下
2022-01-06
  目录