zoukankan      html  css  js  c++  java
  • [数字芯片]SystemVerilog与Modelsim自动化仿真

    简单Verilog编写数字电路的各个模块,必须伴随着一testbench文件用作仿真验证。简单的module当然可以使用简单的Verilog编写一个testbench进行简单的仿真,但一旦遇到功能较为复杂时,Verilog语言的灵活性不足C/C++这类语言。SystemVerilog作为一门针对验证的面向对象的编程语言,能够更好的描述时序,同时具有面向对象语言的灵活性以及重复使用性,能够为工程仿真带来许多便利。接下来,简单使用SystemVerilog对序列检测的module进行仿真验证。

    一、工程框架

    本工程测试一个使用状态机检测“1110010”序列的module,包含五个文件,具体描述如下:

    ├── top.sv:顶层模块,用以连接下列各个模块
    │  
    │   ├── module_bfm.sv: 模块的bus functional model,描述用以连接的interface
    │  
    │   ├── tester.sv: 产生仿真的时序信号
    │  
    │   ├── coverage.sv: 对模块覆盖率的检测
    │  
    │   ├── module.v: 待仿真验证的模块

    由于module是使用Verilog编写的,不能直接使用Interface, 而需要按照Verilog的规范进行连接,而其余SV的module直接使用BFM连接。

    module top();
        seq_fsm_bfm bfm();
        coverage converage_i(bfm);
        tester tester_i(bfm);
        seq_fsm seq_fsm_i(
            .in(bfm.in),
            .out(bfm.out),
            .state(bfm.state),
            .clk(bfm.clk),
            .reset(bfm.rst_n)
        );
    endmodule
    

    二、SystemVerilog的interface使用

    使用Verilog是对于module端口的连接,不管使用顺序还是使用名称连接都容易出错以及极为繁琐。SystemVerilog的interface有点类似C/C++的类,将模块的整个端口信号封装,让其在module之间共享,十分方便,该出定义一个用于连接序列检测module的端口。同时interface还能提供initial与task,以方便时钟以及描述一些简单信号的产生,这里描述时钟、复位信号以及数据信号的交互。

    //Bus Functional Model
    interface seq_fsm_bfm();
        logic clk;
        logic in;
        logic out;
        logic[0:2] state;
        logic rst_n;
        initial begin
             clk=0;
             forever  #10 clk = ~clk;
        end
        task reset();
            rst_n = 0;
            @(posedge clk);
            @(posedge clk);
            rst_n = 1;
        endtask
        task send_data(bit in_data);
            @(posedge clk) in = in_data; 
        endtask
    endinterface //seq_fsm_interface
    

    三、功能覆盖率

    功能覆盖率实际为定义一些coverpoint用以采样信号,进而测试所采的信号是否包含所有状态。我们仅进行一个简单的功能覆盖率的例子,步骤可以简单分为:1、定义coverage;2、采样

    module coverage(seq_fsm_bfm bfm);
    
    logic in;
    logic out;
    logic[2:0] state;
    
    covergroup  cg_cov;
        coverpoint in;
        coverpoint out;
        coverpoint state;
    endgroup
    
    cg_cov oc;
    initial begin
        oc = new();
        forever begin
            @(posedge bfm.clk);
            in  = bfm.in;
            out = bfm.out;
            state = bfm.state;
            oc.sample(); 
        end
    end
    endmodule
    

    coverpoint在默认情况下是包含所有的状态,即以上3比特的state包含8个状态,“000”,“001”,”010“......,对于一些比较多的状态,可以使用排除或列举。使用以上得到的覆盖率报告如下:

    # COVERGROUP COVERAGE:
    # ----------------------------------------------------------------------------------------------------
    # Covergroup                                             Metric      Goal/ Status                    
    #                                                                 At Least                           
    # ----------------------------------------------------------------------------------------------------
    #  TYPE /top/converage_i/cg_cov                          100.0%        100 Covered                   
    #     Coverpoint cg_cov::in                              100.0%        100 Covered                   
    #     Coverpoint cg_cov::out                             100.0%        100 Covered                   
    #     Coverpoint cg_cov::state                           100.0%        100 Covered                   
    #  Covergroup instance /top/converage_i/oc              100.0%        100 Covered                   
    #     Coverpoint in                                      100.0%        100 Covered                   
    #         covered/total bins:                                 2          2                           
    #         missing/total bins:                                 0          2                           
    #         bin auto['b0]                                     498          1 Covered                   
    #         bin auto['b1]                                     502          1 Covered                   
    #     Coverpoint out                                     100.0%        100 Covered                   
    #         covered/total bins:                                 2          2                           
    #         missing/total bins:                                 0          2                           
    #         bin auto['b0]                                     994          1 Covered                   
    #         bin auto['b1]                                       4          1 Covered                   
    #     Coverpoint state                                   100.0%        100 Covered                   
    #         covered/total bins:                                 8          8                           
    #         missing/total bins:                                 0          8                           
    #         bin auto['b000]                                   394          1 Covered                   
    #         bin auto['b001]                                   222          1 Covered                   
    #         bin auto['b010]                                   127          1 Covered                   
    #         bin auto['b011]                                   142          1 Covered                   
    #         bin auto['b100]                                    64          1 Covered                   
    #         bin auto['b101]                                    31          1 Covered                   
    #         bin auto['b110]                                    14          1 Covered                   
    #         bin auto['b111]                                     4          1 Covered   
    

    四、测试器Tester

    这里测试器比较简单,只是复位一下BFM以及产生随机的01信号。

    module tester(seq_fsm_bfm bfm);
        initial begin
            bit in_data;
            bfm.reset();
            repeat(1000) begin
               // $display("@%0t
    ",$time);
                in_data = ($random) %2;
                bfm.send_data(in_data);
            end
        $stop;
        end
    endmodule
    

    五、Modelsim自动化仿真

    Modelsim仿真步骤可以大概分为编译与仿真,仿真每次编译、添加波形、仿真十分繁琐。可以编写do脚本进行自动化仿真,do文件如下:

    if [file exists "work"] {vdel -all}
    vlib work
    
    vlog top.sv tester.sv seq_fsm_bfm.sv coverage.sv seq_fsm.v #编译文件,注意路径,这里与do文件同目录
    
    vopt top -o top_optimized +acc +cover=sbfec+seq_fsm(rtl).  #指定顶层文件,优化
    vsim top_optimized -coverage                               #开始仿真
    
    set NoQuitOnFinish 1
    onbreak {resume}
    log /* -r
    
    add wave seq_fsm_i/*                                       #添加波形
    run -all
    vcover report seq_fsm.ucdb -cvg -details                   #报告覆盖率
    

    编写好run.do文件,Linux下直接运行

    vsim -do run.do
    

    参考:
    克里斯·斯皮尔, SystemVerilog验证 测试平台编写指南
    Ray Salemi, The UVM Primer

  • 相关阅读:
    Canvas 基本绘图方法总结
    js: 从setTimeout说事件循环模型
    HTML5 表单元素
    jQuery选择器
    jQuery基本动画
    HangFire循环作业中作业因执行时间太长未完成新作业开启导致重复数据的问题
    .net 上传文件 Failed to load resource: net::ERR_CONNECTION_RESET Bug 解决
    ABP Zero项目入门踩坑
    关于toggle事件委托的处理
    关于height,line-height导致的样式混乱的问题
  • 原文地址:https://www.cnblogs.com/dzqiu/p/12445191.html
Copyright © 2011-2022 走看看