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

如何通过VPI调用获取Verilog设计指定层级的信号名?

Great question! Building a custom netlist browser using VPI is a common use case for folks building their own EDA tools, and it’s totally manageable once you know the key VPI calls to use. Let’s break down how to fetch signal names at a specific hierarchy level, with examples for both C and Python.

Core Approach

The general workflow boils down to three key steps:

  1. Locate the target hierarchy: Use VPI to get a handle to the specific module/instance you care about.
  2. Iterate over signals: Create an iterator to scan all signal-type objects (wires, regs, nets, ports) within that hierarchy.
  3. Extract signal details: For each signal, pull its name (local or full hierarchical path) using VPI string retrieval functions.

Key VPI Functions You’ll Need

These are the foundational VPI calls for your task:

  • vpi_handle_by_name(): Retrieves a handle to a module/instance using its full hierarchical path (e.g., top.u_dut.u_alu).
  • vpi_iterate(): Creates an iterator for objects of a specific type (like vpiNet, vpiReg, vpiWire, or vpiPort) within a parent module handle.
  • vpi_scan(): Fetches the next object from an iterator (returns NULL when no more objects exist).
  • vpi_get_str(): Gets string attributes of an object—use vpiFullName for the full hierarchical path, or vpiName for the local signal name.
  • vpi_get(): Retrieves integer attributes (like object type, to filter signals if needed).
  • vpi_free_object(): Releases handles and iterators to avoid memory leaks.

Step-by-Step Implementation (C Example)

Since VPI is natively a C API, here’s a code snippet that integrates with a Verilog simulator to fetch signals:

#include <vpi_user.h>

void fetch_target_signals(const char *hier_path) {
    // 1. Get handle to the target module/instance
    vpiHandle mod_handle = vpi_handle_by_name(hier_path, NULL);
    if (!mod_handle) {
        vpi_printf("Error: Could not find module at path %s\n", hier_path);
        return;
    }

    // 2. Create iterator for nets/wires/regs (adjust type as needed)
    vpiHandle sig_iter = vpi_iterate(vpiNet, mod_handle);
    if (!sig_iter) {
        vpi_printf("No signals found in module %s\n", hier_path);
        vpi_free_object(mod_handle);
        return;
    }

    // 3. Iterate through each signal and print its name
    vpiHandle sig_handle;
    while ((sig_handle = vpi_scan(sig_iter)) != NULL) {
        const char *full_hier_name = vpi_get_str(vpiFullName, sig_handle);
        const char *local_name = vpi_get_str(vpiName, sig_handle);
        vpi_printf("Signal: %s (local name: %s)\n", full_hier_name, local_name);
    }

    // Cleanup resources
    vpi_free_object(sig_iter);
    vpi_free_object(mod_handle);
}

// Register the function to run at simulation start
void vpi_register_cb() {
    s_vpi_register_cb cb_data;
    cb_data.reason = cbStartOfSimulation;
    cb_data.cb_rtn = (vpiCbRtn)fetch_target_signals;
    cb_data.user_data = (char *)"top.u_dut"; // Replace with your target hierarchy
    vpi_register_cb(&cb_data);
}

To use this:

  • Compile it into a shared library (e.g., gcc -shared -fPIC my_vpi_tool.c -o my_vpi_tool.so)
  • Load it in your Verilog simulator (e.g., for VCS: vcs -loadvpi ./my_vpi_tool.so:vpi_register_cb design.sv)

Using VPI from Python

If you’re building your tool in Python, you have two main options:

  1. pyvpi: A Python wrapper for VPI supported by some simulators (like Cadence Xcelium or Synopsys VCS). Here’s a quick example:
import pyvpi

def fetch_signals(hier_path):
    # Get handle to target module
    mod_handle = pyvpi.handle_by_name(hier_path)
    if not mod_handle:
        print(f"Error: Module {hier_path} not found")
        return

    # Iterate over all nets
    sig_iter = pyvpi.iterate(pyvpi.vpiNet, mod_handle)
    if not sig_iter:
        print(f"No signals found in {hier_path}")
        return

    # Scan and print each signal
    sig_handle = pyvpi.scan(sig_iter)
    while sig_handle:
        full_name = pyvpi.get_str(pyvpi.vpiFullName, sig_handle)
        local_name = pyvpi.get_str(pyvpi.vpiName, sig_handle)
        print(f"Signal: {full_name} (local: {local_name})")
        sig_handle = pyvpi.scan(sig_iter)

    # Cleanup
    pyvpi.free_object(sig_iter)
    pyvpi.free_object(mod_handle)

# Run when the simulator starts
if __name__ == "__main__":
    fetch_signals("top.u_dut")
  1. ctypes: Wrap your compiled C VPI library and call it from Python. This works if pyvpi isn’t available for your simulator.

Important Notes

  • Hierarchy Paths: Ensure your path uses . to separate module instances (e.g., top.u_dut.u_alu), and matches the case of your Verilog code.
  • Signal Types: Adjust the iterator type (vpiNet, vpiReg, vpiPort, etc.) to capture the specific signal types you need. Use vpi_get(vpiType, sig_handle) to filter objects programmatically.
  • Simulator Compatibility: VPI is part of the IEEE 1364 standard, but some simulators may have minor differences. Check your simulator’s documentation for specifics on loading VPI modules.
  • Memory Management: Always free handles and iterators with vpi_free_object() to prevent memory leaks, especially in long-running tools.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:10:28