• 有限状态机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
  • 相关阅读:
    深入浅出理解索引结构
    SQL数据库碎片检查DBCC SHOWCONTIG含义
    NHibernate和SqlImage
    C#中验证sql语句的方法 (SET PARSEONLY 与SET NOEXEC )
    Webbrowser控件判断网页加载完毕的简单方法
    如何将一个HTML页面嵌套在另一个页面中
    WCF REST Service: InstanceContextMode.PerCall 不管用,无法实现并发
    linux中修改ssh端口
    linux修改主机名(不重启)
    centos使用光盘作为本地的yum源
  • 原文地址:https://www.cnblogs.com/chenman/p/3056016.html
Copyright © 2020-2023  润新知