如何通过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:
- Locate the target hierarchy: Use VPI to get a handle to the specific module/instance you care about.
- Iterate over signals: Create an iterator to scan all signal-type objects (wires, regs, nets, ports) within that hierarchy.
- 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 (likevpiNet,vpiReg,vpiWire, orvpiPort) within a parent module handle.vpi_scan(): Fetches the next object from an iterator (returnsNULLwhen no more objects exist).vpi_get_str(): Gets string attributes of an object—usevpiFullNamefor the full hierarchical path, orvpiNamefor 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:
- 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")
- 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. Usevpi_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
相关产品推荐
相关产品推荐

