FPGA 设计 Verilog 基础(二)

1.1 状态机设计

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

根据状态机的输出信号是否与电路的输入有关分为Mealy型状态机和Moore型状态机。电路的输出信号不仅与电路的当前状态有关,还与电路的输入有关,称为Mealy型状态机。相反,电路的输出仅仅与各触发器的状态有关,不受电路输入信号的影响,称为Moore型状态机。其标准模型如下所示:

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

  • 根据需求和设计原则,确定是Mealy型还是Moore型状态机。
  • 分析状态机的所有状态,对每一状态选择合适的编码方式,进行编码。
  • 根据状态转移关系和输出绘出状态转移图。
  • 构建何使的状态机结构,对状态机进行硬件描述。

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

  • 利用参数定义语句parameter 描述状态机的各个状态名称,即状态编码。状态编码通常有很多种方法,包括自然二进制编码、One-hot编码、格雷编码等。
  • 用时序的always 块描述状态触发器实现状态存储。
  • 使用敏感表和case语句(也可采用if-else)描述状态转换逻辑。
  • 描述状态机的输出逻辑。

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

1.2 一段式状态机

`timescale 1ns / 1ps

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 <= S0;
            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;
                        state <= S0;
                    end
             endcase
    end
    
assign out_o = out_r;
endmodule

1.3 两段式状态机 

`timescale 1ns / 1ps

//两段式状态机
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'b0;
                    Next_state = Next_state;
                end
            default:
                begin
                    out_r =1'b0;
                    Next_state = S0;
                end
         endcase
    end
    
endmodule

1.4 三段式状态机 

`timescale 1ns / 1ps


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:
                begin
                    Next_state <= S1;
                end
            S1: 
                begin
                    Next_state <= S2;
                end
            S2:
                begin
                    Next_state <= S3;
                end
            S3:
                begin
                    Next_state <= Next_state;
                end
            default:
                Next_state  = S0;
        endcase
    end
    
    //输出逻辑
    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
endmodule

猜你喜欢

转载自blog.csdn.net/MaoChuangAn/article/details/83270498