SystemVerilog 編寫FSM


SystemVerilog 編寫FSM


題目

狀態轉移圖

SystemVerilog實現

module ExampleFSM (
    input     logic clk     ,
    input     logic reset   ,
    input     logic X       ,
    output    logic Y       
);

    typedef enum logic [2:0] {A, B, C, D, E} state ; // 定義枚舉類型

    state currentState, nextState ; // 聲明自定義類型變量

    always_ff @(posedge clk , posedge reset)  // 狀態轉移,同步時序
        if (reset) 
            currentState <= A ;
        else
            currentState <= nextState ;

    always_comb  // 狀態轉移條件判斷,組合邏輯
        case (currentState)
            A : if (X)  nextState = C ;
                else    nextState = B ;
            B : if (X)  nextState = D ;
                else    nextState = B ;
            C : if (X)  nextState = C ;
                else    nextState = E ;
            D : if (X)  nextState = C ;
                else    nextState = E ;
            E : if (X)  nextState = D ;
                else    nextState = B ;
            default :   nextState = A ;
        endcase

//    assign Y = (currentState == D | currentState == E) ;  // 組合輸出

    always_ff @(posedge clk , posedge reset)
        if (reset) 
            Y <= 1'b0 ;
        else begin
            Y <= (nextState == D | nextState == E) ;
        end


endmodule

仿真

`timescale 1ns/1ns 
module ExampleFSM_TB ();
    logic        clk=1       ;
    logic        reset     ;
    
    logic        in        ;
    logic        out       ;
    logic        expectOut ;
    logic [31:0] i         ;

    ExampleFSM dut (
        .clk    ( clk    ),
        .reset  ( reset  ),
        .X      ( in     ),
        .Y      ( out    )
    );

    logic [2:0]  testVector [1000:0] ;

    initial begin
        $readmemb ("TestBenchVector.txt", testVector, 0, 19) ;
        i = 0;
        reset = 1; in = 0;

        #200ns; $finish;
    end

    always @(posedge clk) begin
        {reset, in, expectOut} <= #2 testVector[i] ; 
        $display(reset, in, expectOut, $time);
    end

    always @(negedge clk) begin
        if (expectOut !== out) begin
            $display("wrong output for inputs %b, %b != %b, address %d", {reset, in}, expectOut, out, i, $time);
        end
        i = i + 1 ;
    end
    
    always begin
        clk <= 1; #5 ;
        clk <= 0; #5 ;
    end

//-----------------------------------------
//   for VCS generate fsdb file
//-----------------------------------------
initial begin
   $fsdbDumpfile("./digital.fsdb");
   $fsdbDumpvars(0,ExampleFSM_TB,"+all");
   $fsdbDumpflush();
end


endmodule

激勵向量文件:TestBenchVector.txt

10_0
10_0
10_0
00_0
01_0
01_1
01_0
00_0
01_0   // 01_1
00_1
10_1
11_0
11_0
11_0
11_0
11_0
11_0
11_0
11_0
11_0

仿真圖片

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章