You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Verilator仿真中如何通过C++修改SystemVerilog模块参数值

在C++测试平台中修改Verilator编译的SystemVerilog模块参数的方法

SystemVerilog模块的parameter是编译时确定的常量,Verilator会将参数值直接固化到生成的C++代码中,因此无法在运行时修改已实例化模块的参数值。但可以通过以下几种方式实现类似"配置参数"的效果:

方法1:编译时通过Verilator命令行指定参数值

如果只需要在测试前确定参数值,可以在Verilate阶段通过命令行参数覆盖默认值。比如要将WIDTH设为32,执行Verilator时添加:

verilator -cc my_module.sv -DWIDTH=32

这样生成的Vmy_module类会基于WIDTH=32编译。如果需要同时测试多个不同参数的实例,需要多次执行Verilator,每次指定不同的参数,并通过--prefix选项生成不同的类名:

# 生成WIDTH=16的模块类,前缀为Vmy_module_16
verilator -cc my_module.sv --prefix Vmy_module_16
# 生成WIDTH=32的模块类,前缀为Vmy_module_32
verilator -cc my_module.sv -DWIDTH=32 --prefix Vmy_module_32

之后在C++中可以分别实例化不同的类:

VerilatedContext* contextp = new VerilatedContext;
// 实例化WIDTH=16的模块
Vmy_module_16* top16 = new Vmy_module_16{contextp};
// 实例化WIDTH=32的模块
Vmy_module_32* top32 = new Vmy_module_32{contextp};

方法2:将参数替换为运行时可配置的逻辑

如果需要在运行时动态调整参数相关行为,需要修改SystemVerilog模块,将编译时参数替换为运行时可控制的逻辑:

  • 用输入端口控制行为:如果参数用于控制逻辑分支(而非信号位宽),可以将其改为输入端口。例如:
    module my_module (
        input logic i_clk,
        input logic i_rst,
        input logic [3:0] i_width_cfg, // 运行时配置宽度(支持8/16/32位)
        output logic [31:0] o_out // 用最大宽度的输出信号
    );
    always_ff @(posedge i_clk or posedge i_rst) begin
        if (i_rst) begin
            o_out <= '0;
        end else begin
            case(i_width_cfg)
                4'd8: o_out[7:0] <= o_out[7:0] + 1;
                4'd16: o_out[15:0] <= o_out[15:0] + 1;
                4'd32: o_out <= o_out + 1;
            endcase
        end
    end
    endmodule
    
    之后在C++中直接驱动i_width_cfg端口即可模拟不同宽度的行为。

关于你尝试的方法的说明

  • /*verilator public*/标记参数:Verilator会将参数暴露为C++类的静态只读常量(比如Vmy_module::WIDTH),但只能读取,无法修改——因为参数值已经固化到编译后的代码中。
  • DPI接口:DPI仅用于运行时的信号交互,无法修改编译时确定的parameter值,参数在Verilate阶段就已经确定了硬件结构,运行时无法更改。

内容的提问来源于stack exchange,提问作者gsm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:37:29