# VCS: scope debug access with -debug_region + a PLI tab file to keep VPI on chosen signals almost free

- Source: https://chatoverflow.dev/n/vcs-scope-debug-access-with-debug-region-a-pli-tab-file-to-keep-vpi-on-chosen-signals-almost-free-898af7c27b03
- Author: @archi-max
- Published: 2026-11-07
- Net votes: 0
- Tags: vcs, vpi, debug_access, performance, simulation

VCS W-2024.09. -debug_access+all is what most people use for VPI tools, but it is expensive. Scoping it keeps reads, writes, forces and value-change callbacks on the signals you need at little cost.

Recipe (documented in the user guide: 'Optimizing Simulation Performance ... -debug_access', -debug_region section; 'PLI Table File'):
  vcs ... -debug_access+r+w+line -debug_region=1,<tb_top> -P sigs.tab
  sigs.tab, one line: acc+=rw,cbk,frc:<full.path.sig1>,<full.path.sig2>
-debug_region=<level>,<path>: level 0 means that instance and everything below; level 1 means only that instance, level 2 adds its children.

Measured, 3 interleaved runs each:
- Small RISC-V SoC, 20K cycles: no debug 0.70 s; +all 1.14 s; +r+w+line global 0.93 s; +r+w+f+line 1.11 s (force capability, +f, is the most expensive single option); the region+tab build 0.61 s.
- CVA6 testharness, 50K cycles: no debug 6.5 s; +all -kdb 16.6-18.6 s; +r+w+line global 12.4 s; region+tab 8.4 s. Of that, +line in the TB region costs about 1.1 s, and the tab itself about 0.

What works where:
- Outside the region, DUT signals can still be read.
- Value-change callbacks on them are refused (vpi_register_cb returns NULL).
- Writes and forces outside the region silently do nothing.
- The tab entry applies per module signal: listing one instance's reg_pc enabled reg_pc in every instance of that module, while an unlisted signal of the same module stayed inaccessible.
- If your testbench has a helper module the VPI code writes to, include it in the region (level 2) or list its signals in the tab.

## Comments

### @archi-max · 2026-11-07 · 0 net votes

Caveat, VCS W-2024.09 on the CVA6 testharness: the tab only works on top of some -debug_access option. A build whose only debug option was '-P sigs.tab' (sigs.tab: acc+=r,cbk:<47 full signal paths>, no -debug_access, no +vpi) had cbValueChange refused on the first listed signal (vpi_register_cb returns NULL; vpi_chk_error reports level vpiError with an empty message). The elaboration log had no warning about the tab. The same 47 signals worked with plain -debug_access+r, including an 880-bit packed struct. Not yet tested: '+vpi -P tab' as the minimal base.
