SystemVerilog中通过环境变量指定vmem路径的替代方案咨询
问题描述
我有一款类OpenTitan处理器,可通过Verilator进行仿真。当前使用如下top_verilator模块:
module top_verilator(input logic clk_i, rst_ni); ... system #( .SRAMInitFile("/home/user/location/to/vmem") ) u_system ( .clk_i, .rst_ni ); endmodule
因是多人协作项目,我希望通过环境变量读取vmem文件路径。尝试导入DPI-C的getenv函数:
import "DPI-C" function string getenv(input string env_name);
但在新版SystemVerilog中报错:Constant function may not be DPI import (IEEE 1800-2023 13.4.3),请问是否有替代实现方式?
替代实现方式
方法1:Verilator命令行直接传递参数
这是最简洁的方案,无需修改SystemVerilog代码。Verilator支持用-G选项在编译阶段直接覆盖模块参数值,在编译脚本中加入:
verilator ... -GSRAMInitFile=$VMEM_PATH ...
其中$VMEM_PATH是你本地设置的环境变量,每个人只需在自己的环境中配置好该变量即可,完全适配多人协作场景。
方法2:DPI函数结合initial块赋值
如果必须在SystemVerilog内部处理,可通过initial块读取环境变量后传递给模块(需调整system模块的接口,将参数改为输入端口):
修改后的top_verilator模块:
module top_verilator(input logic clk_i, rst_ni); string vmem_path; import "DPI-C" function string getenv(input string env_name); initial begin vmem_path = getenv("VMEM_PATH"); if (vmem_path == "") begin $error("环境变量VMEM_PATH未设置"); $finish; end end // 调整system模块,将SRAMInitFile参数改为输入端口 system u_system ( .clk_i, .rst_ni, .sram_init_path(vmem_path) ); endmodule
方法3:使用$value$plusargs系统函数
利用SystemVerilog内置的$value$plusargs函数从仿真命令行读取参数,结合环境变量传递路径:
top_verilator模块修改如下:
module top_verilator(input logic clk_i, rst_ni); string vmem_path; initial begin if (!$value$plusargs("SRAMInitFile=%s", vmem_path)) begin $error("未通过+SRAMInitFile指定vmem路径"); $finish; end end // 同样需要将system模块的参数改为输入端口 system u_system ( .clk_i, .rst_ni, .sram_init_path(vmem_path) ); endmodule
启动仿真时,将环境变量作为plusargs传入:
./sim +SRAMInitFile=$VMEM_PATH
内容的提问来源于stack exchange,提问作者Bogomips
相关产品推荐
相关产品推荐

