3. VCS命令行参数控制仿真时间

VCS命令行参数控制仿真时间 学习卡片

任务目标

本案例将使用VCS编译并运行一个最小Verilog测试平台,通过命令行参数控制仿真结束时间,并生成VPD格式波形文件,供DVE或Verdi查看。

环境依赖

需要安装Synopsys VCS(本案例使用2018.06版本验证)及配套的DVE波形查看工具。确保vcs命令已加入系统PATH。

设计文件:counter.v

module counter #(parameter WIDTH = 4) (
    input  wire             clk,
    input  wire             rst_n,
    output reg [WIDTH-1:0]  count
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            count <= 0;
        else
            count <= count + 1'b1;
    end
endmodule

测试平台:tb_counter.v

module tb_counter;
    parameter CYCLE = 10;  // 时钟周期 10ns

    reg         clk;
    reg         rst_n;
    wire [3:0]  count;

    // 时钟生成
    initial clk = 0;
    always #(CYCLE/2) clk = ~clk;

    // 复位与激励
    initial begin
        rst_n = 0;
        #(CYCLE*2);
        rst_n = 1;
    end

    // 波形导出(VPD格式)
    initial begin
        $vcdpluson;          // 开启VPD波形记录
        $vcdplusmemon;       // 记录存储器/寄存器变化
    end

    // 仿真结束控制(由命令行+plusarg指定时间)
    initial begin
        $timeformat(-9, 1, " ns", 8);
        wait (rst_n == 1);
        $display("Simulation started at time %0t", $time);
    end

    // 通过命令行参数控制仿真时长
    initial begin
        integer sim_end;
        if (!$value$plusargs("END_TIME=%d", sim_end)) begin
            sim_end = 200;   // 默认仿真 200ns
            $display("END_TIME not specified, using default %0d ns", sim_end);
        end else begin
            $display("END_TIME specified: %0d ns", sim_end);
        end
        #(sim_end);
        $display("Simulation finished at time %0t", $time);
        $finish;
    end

    // 被测模块实例化
    counter #(.WIDTH(4)) u_counter (
        .clk   (clk),
        .rst_n (rst_n),
        .count (count)
    );

    // 监控输出
    initial begin
        $monitor("Time=%0t rst_n=%b count=%d", $time, rst_n, count);
    end
endmodule

编译与运行

在终端执行以下命令(Linux环境):

# 1. 编译(生成可执行文件 simv)
vcs -sverilog +vcs+flush+all -o simv tb_counter.v counter.v -debug_access+all

# 2. 运行仿真,指定仿真结束时间为 500ns
./simv +END_TIME=500

# 3. 运行仿真,使用默认结束时间 200ns
./simv

验证方法

  1. 观察终端输出:仿真启动后,$monitor会打印每个时钟沿的count值,从0递增至15后回卷;仿真结束时打印Simulation finished at time ...,时间应与+END_TIME参数一致。
  2. 检查波形文件:运行结束后,当前目录下应生成vcdplus.vpd文件。执行ls -l vcdplus.vpd确认文件存在且大小非零。
  3. 查看波形:执行dve -vpd vcdplus.vpd打开DVE,添加clk、rst_n、count信号,观察波形是否在复位释放后正常递增。

预期输出(部分)

END_TIME specified: 500 ns
Simulation started at time 10 ns
Time=10 rst_n=0 count=0
Time=15 rst_n=1 count=0
Time=20 rst_n=1 count=1
Time=25 rst_n=1 count=2
...
Simulation finished at time 510 ns

注意:$monitor在时钟上升沿触发,因此时间点均为CYCLE的整数倍加5ns(因#(CYCLE/2)延迟)。仿真结束时间比指定值多一个时钟沿,属正常现象。

常见问题

  • VPD文件未生成:确认编译时使用了-debug_access+all,且测试平台中$vcdpluson位于initial块内。
  • 仿真时间不受控:检查+END_TIME参数是否拼写正确(区分大小写),或改用+END_TIME=500格式(无空格)。
  • 若需FSDB格式:替换$vcdpluson为$fsdbDumpfile("wave.fsdb"); $fsdbDumpvars;,并使用Verdi查看。