zoukankan      html  css  js  c++  java
  • CH02 FPGA设计Verilog基础笔记(二)

     

    1、  状态机设计

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

    根据状态机的输出信号是否与电路的输入有关分为Mealy型状态机和Moore型状态机。电路的输入信号不仅与电路的当前状态有关,还与电路的输入有关,成为Mealy型状态机,即次态=f(现状,输入),输出=(现状,输入);而电路的输出仅仅与各触发器的状态,不受电路输入信号影响或无输入,成为Moore型状态机,即次态=f(现状,输入),输出=f(现状)。其标准模型如下:

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

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

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

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

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

    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                  

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

    两段式状态机

    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        

                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;                              

    enmodule                                        

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

    三段式状态机

    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:

                                         Next_state=Next_state;

                                        

                                default:

                                         Next_state=S0;

                       endcase

             end

            

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

             always@(*)

             begin

                       case(Current_state)

                                S0,S2:

                                         out_r<=1'b0;

                                        

                                S1,S3:

                                         out_r<=1'b1;

                                        

                                default:

                                         out_r<=out_r;

                       endcase

             end assign out_o=out_r;    

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

      一段式状态机、二段式状态机、三段式状态机对应的时序图如下:

  • 相关阅读:
    python 购物车和三级菜单
    python-装饰器
    day3 python 函数
    day3 python 集合 文件
    two day python基础知识
    python-day 1
    Cordova 环境搭建
    javascript在html直接传值
    JavaScript疑难点
    Javascript创建对象的方法
  • 原文地址:https://www.cnblogs.com/TheFly/p/11973347.html
Copyright © 2011-2022 走看看