zoukankan      html  css  js  c++  java
  • 【第一季】CH05_FPGA设计Verilog基础(二)Enter a post title

    第一季】CH05_FPGA设计Verilog基础(二)

    5.1状态机设计

    状态机是许多数字系统的核心部件,是一类重要的时序逻辑电路。通常包括三个部分:一是下一个状态的逻辑电路,二是存储状态机当前状态的时序逻辑电路,三是输出组合逻辑电路。通常,状态机的状态数量有限,称为有限状态机(FSM)。由于状态机所有触发器的时钟由同一脉冲边沿触发,故也称之为同步状态机。

    根据状态机的输出信号是否与电路的输入有关分为Mealy型状态机和Moore型状态机。

    1、Moore型有限状态机:是指那些输出信号仅与当前状态有关的有限状态机,即可以把Moore型有限状态机的输出看成是当前状态的函数。

    2、Mealy型有限状态机:是指那些输出信号不仅与当前状态有关,而且还与所有的输入信号有关的有限状态机,即可以把Mealy有限状态机的输出看成是当前状态和所有输入信号的函数。可见,Mealy有限状态机要比Moore型有限状态机复杂一些。

    Moore型和Mealy型有限状态机的区别:Moore型有限状态机仅与当前状态有关,而与输入信号无关;Mealy型有限状态机不但与当前状态有关,而且还与状态机的输入信号有关。

    状态机的状态转移图,通常也可根据输入和内部条件画出。一般来说,状态机的设计包含下列设计步骤:

    • 根据需求和设计原则,确定是Moore型还是Mealy型状态机;

    • 分析状态机的所有状态,对每一状态选择合适的编码方式,进行编码;

    • 根据状态转移关系和输出绘出状态转移图;

    • 构建合适的状态机结构,对状态机进行硬件描述。

    状态机的描述通常有三种方法,称为一段式状态机,二段式状态机和三段式状态机。状态机的描述通常包含以下四部分:

    1)利用参数定义语句parameter描述状态机各个状态名称,即状态编码。状态编码通常有很多方法包含自然二进制编码,One-hot编码,格雷编码码等;

    2)用时序的always块描述状态触发器实现状态存储;

    3)使用敏感表和case语句(也采用if-else等价语句)描述状态转换逻辑;

    4)描述状态机的输出逻辑。

    下面根据状态机的三种方法,来比较各种方法的优劣。

    5.2一段式状态机

    module detect_1(

    input clk_i,

    input rst_n_i,

    output out_o

        );

    reg out_r;

    //状态声明和状态编码

    reg [1:0] state;

    parameter [1:0] S0=2'b00;

    parameter [1:0] S1=2'b01;

    parameter [1:0] S2=2'b10;

    parameter [1:0] S3=2'b11;

    always@(posedge clk_i)

    begin

    if(!rst_n_i)begin

    state<=0;

          out_r<=1'b0;

        end

    else

    case(state)

    S0 :

    begin

       out_r<=1'b0;

       state<= S1;

    end

    S1 :

    begin

    out_r<=1'b1;

        state<= S2;

    end

    S2 :

    begin

    out_r<=1'b0;

    state<= S3;

    end

    S3 :

    begin

    out_r<=1'b1;

    end

    endcase

    end

    assign out_o=out_r;

    endmodule

    一段式状态机是应该避免使用的,该写法仅仅适用于非常简单的状态机设计,不符合组合逻辑与时序逻辑分开的原则,整个结构代码也不清晰,不利用维护和修改。

    5.3两段式状态机

    module detect_2(

         input clk_i,

         input rst_n_i,

         output out_o

    );

        reg out_r;

        //状态声明和状态编码

        reg [1:0] Current_state;

        reg [1:0] Next_state;

        parameter [1:0] S0=2'b00;

        parameter [1:0] S1=2'b01;

        parameter [1:0] S2=2'b10;

        parameter [1:0] S3=2'b11;

        //时序逻辑:描述状态转换

        always@(posedge clk_i)

        begin

            if(!rst_n_i)

               Current_state<=0;

            else

                Current_state<=Next_state;

        end

        //组合逻辑:描述下一状态和输出

        always@(*)

        begin

            out_r=1'b0;

            case(Current_state)

                S0 :

                    begin

    out_r=1'b0;

                   Next_state= S1;

                    end

                S1 :

                    begin

                  out_r=1'b1;

                  Next_state= S2;

                    end

                S2 :

                    begin

                  out_r=1'b0;

                  Next_state= S3;

                    end

                S3 :

                     begin

                    out_r=1'b1;

                   Next_state=Next_state;

                     end

                endcase

        end

        assign out_o=out_r;    

    endmodule

    两段式状态机采用两个always模块实现状态机的功能,其中一个always采用同步时序逻辑描述状态转移,另一个always采用组合逻辑来判断状态条件转移。两段式状态机是推荐的状态机设计方法。

    5.4三段式状态机

    module detect_3(

            input clk_i,

            input rst_n_i,

            output out_o

            );

        reg out_r;

        //状态声明和状态编码

        reg [1:0] Current_state;

        reg [1:0] Next_state;

        parameter [1:0] S0=2'b00;

        parameter [1:0] S1=2'b01;

        parameter [1:0] S2=2'b10;

        parameter [1:0] S3=2'b11;

        //时序逻辑:描述状态转换

        always@(posedge clk_i)

        begin

            if(!rst_n_i)

                Current_state<=0;

            else

                Current_state<=Next_state;

        end

        //组合逻辑:描述下一状态

        always@(*)

        begin

            case(Current_state)

                S0:

                    Next_state = S1;

                S1:

                    Next_state = S2;

                S2:

                    Next_state = S3;

                S3:

                    begin

                    Next_state = Next_state;

                    end

    default :

    Next_state = S0;

              endcase

        end

        //输出逻辑:让输出out,经过寄存器out_r锁存后输出,消除毛刺

        always@(posedge clk_i)

        begin

            if(!rst_n_i)

                out_r<=1'b0;

            else

            begin

                case(Current_state)

                   S0,S2:

                        out_r<=1'b0;

                   S1,S3:

                        out_r<=1'b1;

       default :

      out_r<=out_r;

                endcase

             end

        end

        assign out_o=out_r;   

    三段式状态机在第一个always模块采用同步时序逻辑方式描述状态转移,第二个always模块采用组合逻辑方式描述状态转移规律,第三个always描述电路的输出。通常让输出信号经过寄存器缓存之后再输出,消除电路毛刺。这种状态机也是比较推崇的,主要是由于维护方便,组合逻辑与时序逻辑完全独立。

  • 相关阅读:
    寒假作业1
    秋季学习总结
    记叙在人生路上对你影响最大的三位老师
    2019年春季学期第二周作业
    币值转换
    第九周作业
    第八周作业
    第七周作业
    第六周作业
    第五周作业
  • 原文地址:https://www.cnblogs.com/milinker/p/6383654.html
Copyright © 2011-2022 走看看