PLI Basics

Programming Language Interface C/C++ connection.

Mohith N
Updated: 19 March 2026
11 min read

The Verilog Programming Language Interface (PLI) is a standardized mechanism that allows external C or C++ programs to interact with a Verilog simulation. It enables designers to extend the simulation environment far beyond what pure Verilog constructs can provide, including custom system tasks, co-simulation with other tools, and direct access to the internal data structures of the simulator.

PLI Architecture: Verilog Simulator and C/C++ InterfaceVerilog SimulationTestbench + DUT$my_task() callSimulation EventsSimulation TimeNet / RegValue DatabasePLI LayerTF / ACC (PLI 1.0)VPI (PLI 2.0 / IEEE 1364)Callback registrationC / C++ ApplicationCustom System Task CodeRead / Write Net ValuesRegister CallbacksCo-simulation InterfaceExternal ModelAnalog / MATLAB etc.callsdataAPIcallsPLI bridges the simulator internal database to external C/C++ code
Figure 1: PLI architecture connecting Verilog simulation engine to external C/C++ code through standardized API layers

Why PLI Exists

Verilog alone cannot cover every verification need. System-level models of analog components, memory models with complex timing, communication protocol stacks, and coverage tools all require capabilities beyond what synthesizable or even simulation Verilog can express efficiently. PLI provides a controlled, standardized API that gives C and C++ code direct access to the simulator data structures, enabling these use cases without modifying the simulator source code.

From the Verilog side, PLI appears as ordinary system task and system function calls prefixed with the dollar sign. The designer calls $my_custom_task(a, b) exactly as they would call $display or $finish. The simulator, when it encounters this call, invokes the registered C function associated with that task name instead of built-in simulator logic.

PLI Evolution: TF/ACC to VPI

PLI has gone through two major generations. PLI 1.0 introduced two libraries: the TF (Task/Function) library and the ACC (Access) library. The TF library allowed C code to retrieve the arguments passed to a system task and return results. The ACC library provided object-level access to the netlist, allowing C code to navigate hierarchy, read and write net values, and traverse the design structure.

PLI 2.0 introduced the VPI (Verilog Procedural Interface), which is now the standard interface defined in IEEE 1364-2001. VPI provides a unified, object-oriented API that supersedes both TF and ACC. It represents every element of the Verilog simulation as a handle, a typed pointer to a simulator object. Functions like vpi_handle(), vpi_get_value(), and vpi_put_value() are the primary means of accessing and modifying simulation data.

VPI Core Concepts

Every object in the simulation is represented by a vpiHandle, which is an opaque pointer returned by VPI traversal and lookup functions. To read the current logic value of a net named 'clk', the C code obtains its handle, prepares a s_vpi_value structure, and calls vpi_get_value() with the handle and a pointer to that structure. The format field in the structure specifies the desired representation such as integer, vector, or string.

Callbacks are another critical VPI mechanism. The vpi_register_cb() function allows C code to request that the simulator call a specified C function when a particular event occurs. Events can include value changes on a net, arrival at a specific simulation time, reaching the end of a simulation step, or the start of simulation. This enables reactive behavior in C code without polling, which would be extremely slow.

Registering a Custom System Task

To add a custom system task to a simulation, the C developer writes two callback functions: a calltf routine that executes when the task is called in simulation, and optionally a compiletf routine that checks the argument types at compile time. These are registered by populating a s_vpi_systf_data structure and passing it to vpi_register_systf() inside the vlog_startup_routines initialization.

The simulator loads the compiled PLI shared library at startup through a command-line argument or a simulator configuration file. Once loaded, every call to the registered task name in the Verilog code will invoke the calltf C function. This mechanism forms the basis for commercial verification IP, waveform dumpers, assertion checkers, and functional coverage tools.

Numerical Example: Using PLI to Measure Simulation Coverage

Consider a toggle coverage tool implemented in C using VPI. For each net in the design, the tool registers a value-change callback. Each time a net toggles from 0 to 1 or 1 to 0, the callback increments a counter for that net. At the end of simulation, the tool computes toggle coverage as the ratio of nets that toggled at least once to the total number of nets.

Example
Given:
Total nets in design (N_total) = 2400
Nets that toggled at least once (N_toggled) = 1980
Coverage threshold for signoff = 95%

Why this formula applies:
Toggle coverage = fraction of nets exercised during simulation.

Formula:
Toggle Coverage (%) = (N_toggled / N_total) x 100

Substitution:
Toggle Coverage = (1980 / 2400) x 100

Calculation:
Toggle Coverage = 0.825 x 100

Final Answer:
Toggle Coverage = 82.5%
This is below the 95% signoff threshold.
420 nets were not toggled. Additional test vectors are needed.
Exam Tip: In GATE and university exams, PLI questions often ask about the role of the calltf and compiletf routines, or the difference between TF/ACC and VPI. Remember: VPI is the modern unified standard (IEEE 1364-2001), TF/ACC are the older PLI 1.0 libraries. VPI uses handles to access all simulation objects.

Practical Applications of PLI

  • Waveform dumping tools like VCD and FSDB writers use VPI callbacks to monitor every signal change and write formatted output files readable by waveform viewers.
  • Co-simulation bridges connect Verilog testbenches to MATLAB Simulink models or SystemC components, enabling mixed-signal and mixed-abstraction verification.
  • Memory and bus functional models for DDR controllers, PCIe, and USB are implemented in C with PLI interfaces so complex protocol behavior is modeled accurately without rewriting in synthesizable Verilog.
  • Assertion checkers and protocol monitors in commercial verification IP use VPI value-change callbacks to track signal sequences and flag violations during simulation.
  • Coverage collection tools register callbacks across thousands of nets and accumulate statistics reported after simulation ends.

Quick Revision

  • PLI (Programming Language Interface) connects Verilog simulators to external C or C++ programs via a standardized API.
  • PLI 1.0 has two libraries: TF (task arguments access) and ACC (netlist object access). Older, being phased out.
  • PLI 2.0 / VPI (Verilog Procedural Interface) is the modern standard in IEEE 1364-2001. Uses vpiHandle for all objects.
  • Key VPI functions: vpi_handle(), vpi_get_value(), vpi_put_value(), vpi_register_cb(), vpi_register_systf().
  • Custom system task registration requires calltf (execution function) and optional compiletf (argument checking) routines.
  • PLI is simulation-only. It has no role in synthesis. PLI code never appears in synthesized netlists.
  • Exam trap: PLI does not make Verilog synthesizable for non-synthesizable constructs. It only extends the simulation environment.

PLI Basics Quiz

Test knowledge of the Programming Language Interface standard.

Question 1 of 3

Q1.What is the primary function of the Verilog Programming Language Interface (PLI)?