Search code examples
environment-variablessimulationsystem-verilogtest-bench

SystemVerilog: String to Circuit Net


Assuming that I set one environment variable before launching a logic simulation of my circuit wrapped in a testbench written in SystemVerilog, I want to check whether it is possible to read the variable and try to map it to a net of the circuit.

For instance:

#### from the bash script that invokes the logic simulator ####
export NET_A=tb_top.module_a.submodule_b.n1
//// inside the tb_top in system verilog ////

import "DPI-C" function string getenv(input string env_name);

always_ff @(posedge clk, nenedge rst_n) begin

    if (getenv("NET_A") == 1'b1) begin

        $display("Hello! %s has the value 1", getenv("NET_A"));
    end 
end

In the example above I simply want to check whether the current net i.e., NET_Ais assigned at a certain point in the simulation the logic value of 1.

Thanks in advance


Solution

  • SystemVerilog has a C-based API (Verilog Procedural Interface VPI) that gives you access to a simulator's database. There are routines like vpi_get_handle_by_name which gives you a handle to an signal looked up by a string name. And then you can use vpi_get_value the gives you the current value of that signal.

    Use of the VPI needs quite a bit of additional knowledge and many simulators give you built-in routines to handle this common application without having to break into C code. In Modelsim/Questa, it is called Signal_Spy.

    But regardless of whether you use the VPI or tool specific routines, looking up a signal by string name has severe performance implications because it prevents many optimizations. Unless a signal represents a storage element, it usually does not keep its value around for queries.

    It would be much better to use the signal path name directly

    vlog ... +define+NET_A=tb_top.module_a.submodule_b.n1
    

    Then in your code

    if (`NET_A == 1'b1) begin