狀態機相關知識點(1)--序列檢測器1100101


1,mealy狀態機與moore狀態機的特征區別?

 

可以從圖中較為明顯的發現:mealy狀態機的輸出是不僅跟當前狀態有關,還跟輸入信號有關。

                                               moore狀態機的輸出只跟當前狀態有關。

因此mealy狀態機的輸出容易受到輸入中的毛刺影響,且moore狀態機相比mealy狀態機在輸出時,多等待一個時鍾周期。

狀態機又可分為二段式和三段式,因此狀態機類型可分為mealy二段,mealy三段,moore二段,moore三段。

2,個人理解中,狀態機最重要的部分是:狀態的轉換-即always組合邏輯部分。通過判斷不同狀態個數,設置合理的寄存器bit位,可避免出現資源的浪費。又當需要對狀態進行精簡時,可使用mealy狀態機。

3,序列檢測器--1100101

moore二段式寫法,狀態轉移圖如下(線還是丑了一些,勉強看吧)

 

 

主程序:

 module sequence_fsm (
    clk,rst,d_in,d_out
);
    input clk;
    input rst;
    input d_in;
    output d_out;

    reg d_out;

    parameter s0 = 3'b000;
    parameter s1 = 3'b001;
    parameter s2 = 3'b010;
    parameter s3 = 3'b011;
    parameter s4 = 3'b100;
    parameter s5 = 3'b101;
    parameter s6 = 3'b110;
    parameter s7 = 3'b111;

    reg [3:0]state,nextstate;

    always @(posedge clk or negedge rst) begin
        if(!rst) begin
            state <= s0;
        end
        else begin
            state <= nextstate;
        end
    end

    always @(state or d_in) begin
        d_out = 1'b0;
        nextstate = 3'bxxx;
        case(state)
        s0: begin
            d_out = 1'b0;
            if(d_in == 1'b0) begin
                nextstate = s0;
            end
            else begin
                nextstate = s1;
            end
        end
        s1: begin
            d_out = 1'b0;
            if(d_in == 1'b0) begin
                nextstate = s0;
            end
            else begin
                nextstate = s2;
            end
        end
        s2: begin
            d_out = 1'b0;
            if(d_in == 1'b0) begin
                nextstate = s3;
            end
            else begin
                nextstate = s2;
            end
        end
        s3: begin
            d_out = 1'b0;
            if (d_in == 1'b0) begin
                nextstate = s4;
            end
            else begin
                nextstate = s1;
            end
        end
        s4: begin
            d_out = 1'b0;
            if (d_in == 1'b0) begin
                nextstate = s0;
            end
            else begin
                nextstate = s5;
            end
        end
        s5: begin
            d_out = 1'b0;
            if (d_in == 1'b0) begin
                nextstate = s6;
            end
            else begin
                nextstate = s2;
            end
        end
        s6: begin
            d_out = 1'b0;
            if (d_in == 1'b0) begin
                nextstate = s0;
            end
            else begin
                nextstate = s7;
            end
        end
        s7: begin
            d_out = 1'b1;
            if (d_in == 1'b0) begin
                nextstate = s0;
            end
            else begin
                nextstate = s2;
            end
        end
        default: begin
            d_out = 1'b0;
            nextstate = s0;
          end
      endcase
    end
endmodule

 

tb程序:

`timescale 1ns/1ps
module sequence_fsm_tb;
    
    reg clk;
    reg rst;
    reg d_in;
    wire d_out;

    sequence_fsm u1(
    .clk(clk),
    .rst(rst),
    .d_in(d_in),
    .d_out(d_out)
);

initial begin
    clk = 1'b1;
    rst = 1'b0;
    #10;
    rst = 1'b1;
end

always #5 clk = ~clk;

initial begin
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 1;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
     #10 d_in = 0;
     $display("display:simulation time is : %t",$time,"the value is :%b",d_in);//前面的賦值驗證正確性,后面采用隨機賦值
     forever #10 begin
        d_in = {$random}%2;
        $display("display:simulation time is : %t",$time,"the value is :%b",d_in);
    end
end
endmodule

局部放大:

 

 由仿真結果可以看出;moore的輸出要晚一個時鍾。

總結:forever只能用於仿真和測試程序,不能進行可綜合設計,且一般用在initial過程塊中,如果在forever語句中沒有加延時語句,則forever將在0延時后無限循環。

          $random%b:如果忽略b的值,則會返回一個隨機的32位有符號數,如果考慮b的值,則會返回[1-b,b-1]這個區間內的等概率有符號隨機數。

          {$random}%b:因為{ }返回的是無符號數,所以可以通過位拼接符將返回的有符號數轉變為無符號數。當b>0時,返回的無符號隨機數的范圍[0,b-1].


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM