SystemVerilog 编写FSM

Posted yllinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

技术图片

以上是关于SystemVerilog 编写FSM的主要内容,如果未能解决你的问题,请参考以下文章

《SystemVerilog验证-测试平台编写指南》学习 - 第2章 数据类型

求systemverilog vimrc 高亮方法(要代码)

如果未设置某个宏,则阻止systemverilog编译

systemverilog中的随机化方法

FPGA/数字IC手撕代码4——FSM状态机的简单应用

凿子中的systemverilog联合类型