SystemVerilog 编写FSM


---- # SystemVerilog 编写FSM ----

好书:
https://github.com/yllinux/blogPic/blob/master/doc/CummingsSNUG2003SJ_SystemVerilogFSM.pdf

https://github.com/yllinux/blogPic/blob/master/doc/CummingsSNUG2019SV_FSM1.pdf

题目

状态转移图

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)  // 状态转移,同步时序,推荐3行式
        if (reset) currentState <= A ;
        else       currentState <= nextState ;

    always_comb  begin // 状态转移条件判断,组合逻辑
        nextState = 3'bxxx ;             //@ loopback,需要写上
        case (currentState)
            A : if (X)  nextState = C ;
                else    nextState = B ;
            B : if (X)  nextState = D ;
                else    nextState = B ;  //@LB
            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
    end

//    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

    always_ff @(posedge clk , posedge reset)
        if (reset) 
            Y <= 1'b0 ;
        else begin
            Y <= 1'b0 ;
            case (nextState)
                D : Y <= 1'b1 ;
                E : Y <= 1'b1 ;
                     // don't need default
            endcase
        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

仿真图片

posted @ 2020-07-04 16:11  纟彖氵戋  阅读(611)  评论(0编辑  收藏  举报