supporting DPI in VHDL - possible scenarios for implementation

From: John Stickley <John_Stickley_at_.....>
Date: Thu Sep 29 2005 - 06:38:39 PDT
Greetings ITC Techies,

As per an action item requested of Duaine and me,
the following e-mail presents possible scenarios for how one
might implement DPI over VHDL purely in a software simulator
environment.

It does not describe scenarios for synthesis of DPI based code
to an emulator environment. However, for this case, function
calls can conceivably be replaced with synthesizeable infrastructure
layered over SCE-MI 1.1 macros where message input and output
ports are used to carry function input and output messages
across the communication link.

In the text below, imported and exported 0-time functions are
described separately.

Specifically VHDL is described is it makes the case that
DPI-like interfaces can be implemented over a language
that does not natively support DPI without requiring
extensions to the language itself. Rather, legal, compliant
attributes are used to alert the language compiler
and/or SCE-MI infrastructure linker to generate extra
infrastructure to support the DPI call interface.

It is important to note that this does not present
any new requirements for SCE-MI that were not already
there for SCE-MI 1.1 macros in terms of infrastructure
linker support. In fact, in some cases it has proven to
be easy to implement a function call based interface
since, on most industrial HDL software simulators, some
capability already exists for function call type interfaces
- such as foreign functions in VHDL and PLI user defined tasks in Verilog.

--------------------------------------------------------------
Imported 0-time functions

Imported functions can be declared in VHDL as procedures and
can be called from user clocked RTL processes. Here is an example
of a simple user application written in VHDL that makes use of
the proposed DPI imported function interface:

entity PipelineEgressTransactor is port(
      TokenOut: in std_logic_vector(127 downto 0);
      Clock, Reset: in std_logic);
end PipelineEgressTransactor;

architecture DPI of PipelineEgressTransactor is
      --This is a Imported Function declaration--
      procedure UploadEgressTransaction(
          signal countOut : in std_logic_vector (31 downto 0)
          signal dataOut : in std_logic_vector (63 downto 0);
          signal statusOut : in std_logic_vector (31 downto 0)) is
      begin end procedure;
      attribute foreign of UploadEgressTransaction:
          procedure is "sce_mi import DPI-C";

begin
      process (Clock) begin
          if(Reset /= '1' and IsStdLogicVectorZero(TokenOut) = '0') then
              UploadEgressTransaction(
                  TokenOut(31 downto 0),
                  TokenOut(95 downto 32),
                  TokenOut(127 downto 96));
          end if;
      end process;
end DPI;

There are a number of scenarios in which an implementation can
implement the "guts" of the empty placeholder function,
UploadEgressTransaction().

By no means do we try to dictate any one of those ways here.
We only want to suggest possibilities for implementation.
Different vendors would most likely choose different solutions
depending on what is optimal in their environment.

3 of those possibilities are mentioned here:

1. The vendor can modify their compiler so that the empty procedure
    is automatically replaced directly with generated native code that
    hooks into an infrastructure implementation that directly
    communicates to C using whatever VHDL foreign language interface
    (FLI) that is supported by that vendor.

    This foreign language interfacing mechanism would look similar
    to the one that SCE-MI 1.1 macros would have to use today.

    Note: No source code transformation is required with this approach
    as the extra infrastructure is emitted directly into the
    native code output unit.

2. VHDL foreign functions - this is similar to 1 above. If a
    vendor has created a mechanism in their simulator to implement
    "foreign functions" as designated by the `FOREIGN attribute
    as described in the LRM, this mechanism can be easily be leveraged
    to implement imported DPI functions. In fact, a very good case
    can be made that such an implementation could be relatively easy
    since this feature already supports function calling semantics
    and most vendor have already have some sort of support for
    foreign functions.

    Using the `FOREIGN attribute syntax shown in the example
    above (which is also consistent with LRM recommended uses
    of this attribute to denote foreign functions), the vendor
    could directly implement DPI imported functions as foreign
    functions using their vendor specific mechanism that is
    already in place for foreign functions.

3. If the vendor simulator is mixed language and already supports
    a SystemVerilog DPI interface, the internals of the VHDL call
    could be a wrapper that directly calls a SystemVerilog DPI
    imported call.

    This option is similar to 2 except it utilizes existing DPI
    capability rather than existing foreign function capability.

    The modified internals for the VHDL call could either be
    directly generated as native code (as described in 1 above)
    or the user's source code could be slightly transformed to
    give the empty placeholder function a body that calls the DPI
    function.

-------------------------------------------------------------------------
Exported 0-Time Functions

The SCE-MI 2 DPI proposal states that 0-time procedures in
VHDL can be attributed as exported DPI functions and called
from C.

Exported functions can potentially do the following:

   1. C->HDL message passing or config ops (input args)
   2. C->HDL query ops (output args)

The exported function would be a VHDL procedure that
can do assignments of input formal argument values to
surrounding signals for passing input messages and can do
assignments of surrounding signal values to output formal
arguments for passing output messages.

To achieve this, an exported function can be declared as a
specially attributed procedure in the declarative region of
an architecture.

In the following user VHDL application example, the exported
function, 'ServiceIngressTransaction()' assigns to signals
'serviceCallDetected',
'holdingCount', 'receivedCount', 'receivedData' and
'receivedStatus' declared in the architecture scope.

-- the following is a Exported Function definition--
procedure ServiceIngressTransaction (
     signal holdCountIn : in integer;
     signal receivedCountIn : in std_logic_vector (31 downto 0);
     signal dataIn : in std_logic_vector (63 downto 0);
     signal statusIn : in std_logic_vector (31 downto 0)) is
begin
     serviceCallDetected <= '1';
     holdingCount <= holdCountIn;
     receivedCount <= receivedCountIn;
     receivedData <= dataIn;
     receivedStatus <= statusIn;
end procedure;
attribute foreign of ServiceIngressTransaction:
     procedure is "sce_mi export DPI-C";

process begin
     wait until (Clock'event and Clock = '1');
     if(serviceCallDetected = '1') then serviceCallDetected <= '0';

     if (Reset /= '1') then
         while holdingCount > 0 loop
             holdingCount  <= holdingCount - 1;
             wait until (Clock'event and Clock = '1');
         end loop;

         TokenIn <= receivedStatus & receivedData &  receivedCount;
         wait until (Clock'event and Clock = '1');

         TokenIn <= (others => '0');
         wait until (Clock'event and Clock = '1');
     end if;
end process;

Here again are 3 possible scenarios for implementing this exported function.

1. The vendor can modify their compiler so that in addition to generating
    simulation code for the user's architecture and procedure, it also
    generates an additional process block in the same architecture
    scope. This process block communicates directly with the C side
    using special synchronization signals together with whatever
    VHDL foreign language interface (FLI) that is supported by that
    vendor.

    The special process block would wait until one of the synchronization
    signals indicates that a call to the exported function
    was initiated. It would then take the input data arguments
    passed along from the C side via the FLI and make
    a call to the actual exported procedure defined by the
    user. The output arguments of the call would be passed
    back to C side via the FLI.

    It might look something like this:

     -- Auxiliary process to manage calls to exported
     -- ServiceIngressTransaction() function
     ServiceIngressTransaction_wrapper: process
         -- These variables updated via C interface API
         variable holdCountIn : integer;
         variable receivedCountIn : std_logic_vector (31 downto 0);
         variable dataIn : std_logic_vector (63 downto 0);
         variable statusIn : std_logic_vector (31 downto 0);
     begin
         -- Wait for signal triggered via PLI, VHPI, FLI
         -- or similar C-API interface.
         wait on ServiceIngressTransaction_trigger;

         -- Make the actual call to the exported function (args
         -- are set in wrapper
         ServiceIngressTransaction (
             holdCountIn, receivedCountIn, dataIn, statusIn );

         -- Toggle trigger to notify C side (via value change callback)
         -- that call is complete.
         ServiceIngressTransaction_trigger
             <= ~ServiceIngressTransaction_trigger;
     end process ServiceIngressTransaction_wrapper;

2. In a mixed language simulator this process could
    be a Verilog process that is placed completely outside the
    user's original source unit and makes the call to the exported
    function using cross scope references. Using this approach would
    require absolutely no source code transformation and it could be
    implemented with no alterations to the vendor's compiler as well.
    Rather an extra module would be created by the infrastructure linker
    containing the cross scoping wrapper processes and could be compiled
    into its own separate database unit that is elaborated along
    with the rest of the design.

3. If the vendor simulator is mixed language and already supports
    a SystemVerilog DPI interface, an actual DPI exported function
    can be added as a wrapper that then calls the VHDL exported
    function.

-- johnS

______________________________/\/            \     \
John Stickley                   \             \     \
Mgr., Acceleration Methodologies \             \________________
Mentor Graphics - MED             \_
________________________________________________________________
Received on Thu Sep 29 06:40:03 2005

This archive was generated by hypermail 2.1.8 : Thu Sep 29 2005 - 06:40:26 PDT