有限状态机FSM的写法

  描述状态机推荐采用三段式FSM描述方法。这种写法使用3个always模块,一个always模块采用同步时序的方式描述状态转移,一个always采用组合逻辑的方式判断状态转移条件,描述状态转移规律,第三个always模块使用同步时序电路描述每个状态的输出。

  这种做法好处在于便于阅读、理解、维护,更重要的是利于综合器优化代码。利于用户添加合适的时序约束条件,利于布局布线器实现设计。

  三段式FSM写法参考如下程序:

module fsm(in1, in2, clk, rst_n, out1, out2, err);
input        in1, in2;
input        clk, rst_n;
output        out1, out2;
output        err;

reg            out1, out2;
reg            err;
reg[2:0]    CS, NS;

parameter[2:0]    IDLE    = 3'b000,
                S1      = 3'b001,
                S2       = 3'b010,
                ERROR    = 3'B100;
                
//时序逻辑,状态转移
always @(posedge clk or negedge rst_n)
begin
    if (!rst_n)
        CS <= IDLE;
    else
        CS <= NS;
end

//组合逻辑,状态转移条件判断
always @(rst_n, CS, in1, in2)
begin
    NS = 3'bX;
    
    case (CS)
        IDLE:
        begin
            if (!in1)          NS = IDLE;
            if (in1 && in2)     NS = S1;
            if (in1 && !in2)    NS = ERROR;
        end
        S1:
        begin
            if (!in2)           NS = S1;
            if (in1 && in2)     NS = S2;
            if (!in1 && in2)    NS = ERROR;
        end
        S2:
        begin
            if (in2)            NS = S2;
            if (in1 && !in2)    NS = IDLE;
            if (!in1 && !in2)   NS = ERROR;
        end
        ERROR:
        begin
            if (in1)            NS = ERROR;
            if (!in1)           NS = IDLE;
        end
        default: NS = IDLE;
    endcase;
end

//时序逻辑,状态机输出
always @(posedge clk or negedge rst_n)
begin
    if (!rst_n)
        {out1, out2, err} <= 3'b000;
    else
    begin
        {out1, out2, err} <= 3'b000;
        case (NS)
            IDLE:     {out1, out2, err} <= 3'b000;
            S1:       {out1, out2, err} <= 3'b100;
            S2:       {out1, out2, err} <= 3'b010;
            ERROR:    {out1, out2, err} <= 3'b111;
            default: {out1, out2, err} <= 3'b000;
        endcase
    end
end

endmodule
原文地址:https://www.cnblogs.com/chenman/p/3056016.html