如何使用 SystemVerilog 设置环境变量?

How to set Environment Variables with SystemVerilog?

我当前的项目在 perl 模块中设置了一个环境变量,然后从 SystemVerilog 文件调用一个使用该变量的函数。要求是我们在 perl 模块中添加的任何内容都在调用时出现在环境变量中。

然而,问题是 perl 模块和 systemverilog 调用之间的某些东西干扰了我的变量。我不知道它是什么,解决这个问题与我的项目无关,所以我只想将变量设置为 perl 模块设置的任何值并继续。

Perl 中有一个方便的 getenv 函数,我也可以在 SV 中使用 getenv。但是好像没有setenv。在 SV 中设置环境变量的合适方法是什么?

是否使用 $system() 调用从 SystemVerilog 中调用 perl 代码?如果是这样,perl 代码所做的环境更改肯定不会传播回 SV 世界,因为这些更改仅在 $system() 子进程的环境中进行。

setenv() 系统调用在我使用的所有工具(最近的 Fedora OS、Mentor/Cadence/Synopsys 模拟器的最新版本)中通过 SystemVerilog DPI-C 为我工作,但可能有一些它不可用的较旧的 *nix 系统。我使用了 "man 3 setenv" 中给出的原型。查看其他 Whosebug 论坛上的讨论,似乎使用 putenv() 并不是一个好主意,尤其是在 DPI 中,您不知道用于 DPI 字符串参数的内存会发生什么。 setenv() 复制了它的参数字符串,应该不会有这个问题的风险。

在我看来,如果您的工具流程没有按照您预期的方式正确传播环境变量,那么您遇到的问题比如何处理来自 SystemVerilog 的 env 还要大。我特别选择不向 svlib 实用程序库添加环境修改函数,正是因为使用环境是在 SV 模拟中传递信息的一种非常糟糕的方式。我想如果您需要为某个外部程序设置一个环境,然后使用 SV $system() 调用来调用它,那将是有意义的。

嗯......结果证明答案很简单,但这是这个问题的唯一线索所以我会留下它以防其他人发现自己处于类似情况:

SystemVerilog 没有 setenv( ) 或 getenv( ) 函数。它们实际上是使用以下结构从 C 中实现的:

module/program foo();

    import "DPI-C" function <return type> foonction(<function arguments>);

endmodule/program; 

显然在我的例子中,有人为 getenv( ) 做了这个,但从来没有为 setenv( ) 做过。我没听懂的原因是因为我的相关代码是通过以下方式包含的:

**foo.sv**
if(var.bit) begin
    call_function();
    use_environment_variable();
end

**bar.sv**
module bar();
    <do stuff>
    `include foo.sv <-- foo code is copied in after calculations have occured.
endmodule

尝试在 foo.sv 中导入 DPI-C 将触发错误,因为导入将在计算完成后到达。为了解决这个问题,我们需要像这样在 bar.sv 中导入:

module bar();
   import "DPI-C" function int setenv(string name, string value, int override);
   <do stuff>
   `include foo.sv
endmodule

从 SV 设置环境变量不是很有用,除非你是 运行 另一个 SV 的可执行文件。

如果要获取环境变量,可以使用Verilab's svlib函数:

function automatic string sys_getEnv(string envVar);
function automatic bit sys_hasEnv(string envVar);