VHPI Applications


VHPI (VHDL Procedural Interface) provides standard means to access data in VHDL models elaborated and simulated in the simulator. The interface is implemented as a library of C functions, and is intended to meet the VHPI standard being developed by IEEE. VHPI applications must be compiled and linked to a shared library. They can be further bound with VHDL design units and subprograms. To learn how to build VHPI Applications, see Building VHPI Applications. To learn how to use VHPI Applications, see Using VHPI Applications. For a list of supported constructs, see Supported Functions and Objects.

VHPI provides the following functionality:

Building VHPI Applications

Header Files

The \PLI\Include and \interfaces\include subdirectories of the Active-HDL and Riviera-PRO installation directories, respectively, contain header files that must be included in your PLI application.

#include <vhpi_user.h>
#include <aldecpli.h>

Registering VHPI Applications

Each VHPI library must include at least one function to register VHPI applications. A pointer to this function is located in the vhpi_startup_routines array. The array must be null-terminated. Names of registering functions are arbitrary.

PLI_VOID (*vhpi_startup_routines[])() = {

Functions that register VHPI applications, such as startup_1 and startup_2, use the standard VHPI function vhpi_register_foreignf(). The vhpi_register_foreignf() function gets a pointer to the vhpiForeignDataT structure as a parameter. The structure specifies how a VHPI function is to be registered.

PLI_VOID startup_1() {
vhpiForeignDataT foreignData = {
              foreignData.kind        = vhpiArchF,
              foreignData.libraryName = "myvhpi",
              foreignData.modelName   = "myvhpitask",
              foreignData.elabf       = elab_arch,
              foreignData.execf       = sim_arch };

The vhpiForeignDataT structure is defined in the vhpi_user.h header file.

vhpiForeignT kind

The field specifies which VHDL statement will be represented by the VHPI application.

char *libraryName

The name of the library containing VHPI routines. If you omit the extension, the default extension is added automatically. If the library cannot be found in the current directory, the locations pointed by the PATH system variable are checked.

char *modelName

The name of the VHPI model that is used to locate a model in the shared library. Note that the same name must be used during registration of the VHPI model on the VHDL side of the interface.

void (*elabf) (const vhpiCbDataT* cbdata)

Specifies an elaboration function name. The null value specifies that no elaboration function is required for the foreign model. When registering a foreign procedure or function, this field should be set to null. When registering a foreign architecture, the field should contain the name of a function associated with the architecture.

void (*execf) (const vhpiCbDataT* cbdata)

Specifies the name of a registered execution function when registering a foreign procedure or function.

NOTE: Foreign architectures can also be registered during elaboration using the -loadvhpi argument for the asim command. In this case, you do not have to register a VHPI application in the C code as it is described above. Note that -loadvhpi argument can be applied only to foreign architectures; it cannot be used for foreign functions nor procedures.

Using VHPI Applications

VHPI applications are registered using the foreign attribute which is declared in the std library in the standard package. A value of the foreign attribute is a string that contains a sequence of identifiers.

attribute foreign of <unit_or_subprogram_name> : architecture is "VHPI <library_name>; <model_name>";

The foreign models could be defined as follows:

entity test is end;

-- foreign architecture registration
architecture foreign_arch of test is
  attribute foreign of foreign_arch : architecture is "VHPI lib_name; arch";

library ieee;
use ieee.std_logic_1164.all;

entity tb is

architecture tb_arch of tb is
  component test
  end component;

-- foreign procedure registration
procedure proc;
attribute foreign of proc : procedure is "VHPI lib_name; proc";

-- foreign function registration
function func return integer;
attribute foreign of func : function is "VHPI lib_name; func";

signal a : integer := 1;

  uut: test;
  process begin
    a <= func;
    wait for 1 ns;
  end process;


The following example shows how to set a callback that reacts to writing data to memory. When a memory write is executed, the callback returns a current time, value and memory cell where the data was recorded.

library ieee;

entity top is

architecture top of top is
    procedure callback_event;
        attribute foreign of callback_event: procedure is "VHPI test; test_init";

    type MEM is array ( NATURAL range <> ) of BIT_VECTOR( 7 downto  0 );
    signal memory_var : MEM( 3 downto 0 );

    proc1: process

        wait for 1 ps;    memory_var(0) <= "00111000";
        wait for 1 ps;    memory_var(2) <= "10010010";
        wait for 1 ps;    memory_var(3) <= "01101000";
        wait for 1 ps;    memory_var(0) <= "11100110";
        wait for 1 ps;    memory_var(2) <= "00000011";
        wait for 1 ps;    memory_var(3) <= "00110000";

    end process;

The memory is represented by the one-dimensional array memory_var of the BIT_VECTOR type. Registering is executed by the callback_event procedure called in the proc1 process. The procedure is a VHPI application that is expected to be localized under the test_init name in the test shared library as it is denoted in the procedure registration. The C++ part of the example is shown below.

#include <fstream>
#include <string>

#include <vhpi_user.h>
#include <aldecpli.h>

std::ofstream file;

PLI_VOID ValueChangeEvent (const struct vhpiCbDataS * cbDatap) {

    vhpiValueT* Value =  cbDatap->value;

    file << vhpi_get_str( vhpiFullNameP, cbDatap->obj ) << "\n";
    file << "    at time   : " << cbDatap->time->low << "\n";
    file << "    has value : " << Value->value.str   << "\n\n";
    file << std::flush;

PLI_VOID register_cb ( const struct vhpiCbDataS* cb_p ) {

    vhpiCbDataT      cbDataAction;
    vhpiValueT       *Value;
    vhpiTimeT        *Time;

    vhpiHandleT hnd       = vhpi_handle_by_name("top.memory_var", NULL);
    vhpiHandleT hnditr    = vhpi_iterator(vhpiIndexedNames, hnd);

    Value = (vhpiValueT*) malloc ( sizeof(vhpiValueT) );
    Time  = (vhpiTimeT*)  malloc ( sizeof(vhpiTimeT) );

        Value->format            = vhpiStrVal;
        Value->bufSize           = 0;
        Value->value.intgs       = 0;
        cbDataAction.cb_rtn      = ValueChangeEvent;
        cbDataAction.reason      = vhpiCbValueChange;
        cbDataAction.time        = Time;
        cbDataAction.value       = Value;
        cbDataAction.user_data   = NULL;

  while ( vhpiHandleT hndByIdx = vhpi_scan (hnditr) ) {
            cbDataAction.obj         = hndByIdx;
            vhpi_register_cb (&cbDataAction, vhpiReturnCb);

// callback registration
PLI_VOID startup_1() {
    vhpiForeignDataT foreignData =  {vhpiProcF, "test.dll", "test_init", NULL, register_cb};

PLI_VOID (*vhpi_startup_routines[])() = { startup_1, 0L };

The functionality of the VHPI procedure callback_event is defined by the register_cb function. The register_cb function is created on the basis of the VHPI function vhpi_register_cb that describes how the callback is to be registered. The function behavior is specified by the cbDataAction argument of the vhpiCbDataT structure type.

The cb_rtn structure field specifies the callback routine name, that is, the routine to be executed when an event for which the callback was registered occurs. The specified callback routine is ValueChangeEvent. The ValueChangeEvent routine dumps a callback time, name and value of a signal that triggered the callback to the results.txt output file.

The reason field specifies the reason for the callback is executed. It is set to vhpiCbValueChange so that the callback is executed when a value of an object changes. The obj field specifies the handle to the object on which the callback is set. The time and value fields specifies where the event time and the value of the object that triggered a callback are to be written.

The vhpi_register_cb function is called in the while instruction for each element of the top.memory_var array, so after executing of the while instruction the callbacks are set for each array element.

The callback_event procedure registers callbacks at the very beginning of the proc1 process. Therefore, each event occurrence on a memory_var element during the process execution causes a call of the ValueChangeEvent routine. The output file is as follows:

    at time   : 1
    has value : 00111000

    at time   : 2
    has value : 10010010

    at time   : 3
    has value : 01101000

    at time   : 4
    has value : 11100110

    at time   : 5
    has value : 00000011

    at time   : 6
    has value : 00110000

Supported Functions and Objects

The following VHPI functions are supported:

The following VHPI objects are supported:

Non-standard Extensions to VHPI


The vhpiLanguageP property allows identifying the source language of an object whose handle was passed as an argument to the vhpi_get function.

The value returned by the vhpi_get function for the vhpiLanguageP property can be one of the following constants:

Example (vhpiLanguageP)

#include "vhpi_user.h"
int what_language ( char* path ) {
  vhpiHandleT handle = vhpi_handle_by_name ( path, 0 );
  if ( !handle ) return -1;
  vhpiIntT language = vhpi_get ( vhpiLanguageP, handle );

  switch ( language )
    case vhpiVerilog :   // Verilog
      return 1;
    case vhpiVHDL :      // VHDL
      return 2;
    case vhpiUndefined : // Not known
      return 4;
    default :            // an error
      return -1;

The above example shows a VHPI function that checks the source language of an entity whose hierarchical name is given with the path parameter. A handle to the specified object is obtained with the vhpi_handle_by_name function. Then, a value of the vhpiLanguageP property is retrieved with the vhpi_get function. The case statement checks the value of the retrieved property for the source language.

Unsupported VHPI Functionality

The following functionality outlined in the VHPI standard is not supported:

The following VHPI functions are not implemented:

The following VHPI relationships are not supported:

Printed version of site: www.aldec.com/jp/support/resources/documentation/articles/1457