• 【原创】有限状态机设计


    1. 状态机的基本概念

    数字系统分两大类FSM:Moore和Mealy。FSM是用来表示有限个状态之间转移和动作等行为。

    1.2 Moore状态机

    Moore FSm由Edward F. Moore 提出。特点是输出只由当前状态确定,与输入没有关系。

    Moore FSM状态图中每一个状态都包含一个输出信号。一旦当前状态改变几乎会立即导致输出改变。Moore FSM输出在时钟脉冲的有效边沿后的有限个门延迟之后才会达到稳定值,Moore最大的特点是将输入和输出信号隔离开来。

    图1 Moore 状态机示意图

     

    1.3 Mealy状态机

      Mealy FSM是由G.H.Mealy在1951年提出来的,输出和当前状态也和输入有关系,因此在状态转移图中每条转移边需要包含输入和输出的信息,每一个Mealy机都有一个等价的Moore机。

    Mealy FMS的输出直接受输入的直接影响,而输入的信号可能在一个时钟周期内任何时刻发生改变,所以Mealy FSM对输入的响应要比Moore FSM早一个周期,而且输入信号的噪声也可能影响到输出信号。

    图2 Mealy 状态机示意图

    1.3状态初始化

       初始化是对FSM内部的所有reg还有mem进行复位和初始化,一定要防止出现伪初始化或者不完全初始化的情况,特别针对一些总线或者有位宽要求的信号和变量。

    未完全初始化的示例:

    always    @(posedge clk or negedge rst_n)
        begin 
            if(!rst_n)
                state <= IDLE;
            else case(state)
                        IDLE:begin
                                    S[0] <=1'b1;
                                    state <=ACT1;
                              end
                        ACT1:begin
                                    S[1] <=1'b1;
                                    state <=ACT2;
                              end
                        ACT2:begin
                                    S[2] <=1'b1;
                                    state <=CMP;
                              end
                        CMP:begin
                                    S[3] <=1'b1;
                                    state <=IDLE;
                              end
                        default:state <= IDLE;
                    endcase
        end 

      这个FSM表示在不同的状态给S[3:0]的不同位置,在异步复位的地方只是对state初始化,但是对于S[3:0]并没有初始化,解决这个初始化的最好方法就是对所有的输出都进行初始化。从根本上讲,所有的初始化动作都需要对FSM中的每个输出信号和变量进行初始化,另外要特别注意default分支语句,避免进入死锁。修改如下例:

    always    @(posedge clk or negedge rst_n)
        begin 
            if(!rst_n)
                begin
                    state <= IDLE;
                    S <= 4'b0000;
                end
            else case(state)
                        IDLE:begin
                                    S[0] <=1'b1;
                                    state <=ACT1;
                              end
                        ACT1:begin
                                    S[1] <=1'b1;
                                    state <=ACT2;
                              end
                        ACT2:begin
                                    S[2] <=1'b1;
                                    state <=CMP;
                              end
                        CMP:begin
                                    S[3] <=1'b1;
                                    state <=IDLE;
                              end
                        default:state <= IDLE;
                    endcase
        end 

    1.4 Full Case和Parallel Case

      Full Case在Sunplify中一般采用/*synthesis full_case*/来实现,Parallel case在Sunplify中一般采用/*synthesis parallel_case*/来实现

     1.4.1 Full Case下FSM设计

    module syntax_ctrl(s0,s1,s2,s3,next)
     //数据声明
        input s0,s1,s2,s3;
        output  reg[1:0] next;
     //
        parameter IDLE = 4'b1xxx,
                     READ = 4'bx1xx,
                     TALK = 4'bxx1x,
                     STOP = 4'bxxx1;
     //
        always    @(s0 or s1 or s2 or s3)
            begin 
                         casex({s0,s1,s2,s3})
                            IDLE: 
                                        next <=0;
                            READ: 
                                        next <=1;
                            TALK:  
                                        next <=2;
                            STOP: 
                                        next <=3;
                            default: next <=0;
                        endcase
            end 
        endmodule 

    1.4.2 Parallel case FSM实现

    module syntax_ctrl(s0,s1,s2,s3,next)
     //数据声明
        input s0,s1,s2,s3;
        output  reg[1:0] next;
     //
        parameter IDLE = 4'b1xxx,
                     READ = 4'bx1xx,
                     TALK = 4'bxx1x,
                     STOP = 4'bxxx1;
     //
        always    @(s0 or s1 or s2 or s3)
            begin 
                         casex({s0,s1,s2,s3})
                            IDLE: 
                                        next <=0;
                            READ: 
                                        next <=1;
                            TALK:  
                                        next <=2;
                            STOP: 
                                        next <=3;
                            default: next <=0;
                        endcase
            end 
        endmodule 

      两者区别在:

       Full case中FSM把所有的编码向量与case中某个分支匹配,如果编码是4bits则有16个状态编码向量同case中的某个分支映射起来。

       Parallel case 中,每个case中判断条件表达式有且仅有一个分支语句与之对应。

    Full case可以增加设计的安全性,Parallel case可以优化状态机的逻辑编码,不过,一般比较推荐采用Parallel case,因为从功能和门级仿真的结果来看,Parallel case比较符合硬件行为的要求。

    注意:在一般的仿真工具并不认识上面所述的注释,所以一般而言当需要使用优先级编码逻辑的时候,采用casez语句,可以确保case语句涉及的是全面的;当要使用Parallel case时采用case语句,而且case语句中各条分支语句必须是相互排斥的。

  • 相关阅读:
    PHPUnit
    变长参数处理
    springMVC课程笔记(二)springMVC组件配置
    URL编码以及GET和POST提交乱码解决方案
    springMVC课程笔记(一)springMVC架构原理分析
    ELK(ElasticSearch, Logstash, Kibana) 实现 Java 分布式系统日志分析架构
    Java 标准 IO 流编程一览笔录( 下 )
    Java 标准 IO 流编程一览笔录( 上 )
    Zookeeper系列(十四)Zookeeper的数据与存储
    Zookeeper系列(十三)Zookeeper的请求处理
  • 原文地址:https://www.cnblogs.com/woshitianma/p/2849580.html
Copyright © 2020-2023  润新知