2

Suppose I have a packed struct:

typedef struct packed {
   logic a;
   logic [7:0] b;
   bit  [7:0] c;
   logic [7:0] [31:0] d;
} my_struct;

And I want to pass it into a C function:

import "DPI" context function int my_dpi_function (input my_struct data);

How do I read values on C side?:

int my_dpi_function (void* data) 
{  
    ... ?

    return 0;
}
Greg
  • 18,111
  • 5
  • 46
  • 68
random
  • 3,868
  • 3
  • 22
  • 39
  • yes you can use them. At `c` side you just get a stream of bits. You have walk it, using `get` functions from `svdpi.h` to recreate your struct fields. – Serge Sep 19 '19 at 20:13

1 Answers1

3

The type you need is defined in the svdpi.h header:

svLogicVecVal

So, you need something like:

int my_dpi_function (svLogicVecVal* data) 
{  
    ... 
    return 0;
}

svLogicVecVal is itself a struct. It has two fields - aval and bval (or sometimes, eg in Cadence, a and b). From svdpi.h:

typedef struct t_vpi_vecval {
#ifdef P1800_2005_VECVAL
    uint32_t a;
    uint32_t b;
#else
    uint32_t aval;
    uint32_t bval;
#endif
} s_vpi_vecval, *p_vpi_vecval;
#endif

/* (a chunk of) packed logic array */
typedef s_vpi_vecval svLogicVecVal;

The aval and bval fields are encoded thus (the so-called "canonical representation"):

bval aval | 4-state verilog value
----------|----------------------
  0    0  |   0
  0    1  |   1
  1    0  |   X
  1    1  |   Z

So, you can access the aval and bval fields in your C. It turns out that for vectors wider than 32-bits, the most-significant 32-bit word is at the highest pointer address.


https://www.edaplayground.com/x/2k33

SV

module test;

  typedef struct packed {
    logic a;
    logic [7:0] b;
    bit  [7:0] c;
    logic [7:0] [31:0] d;
  } my_struct;

  import "DPI-C" context function int my_dpi_function (logic [272:0] data);

  initial
    begin
      automatic my_struct data = '{1'b0,8'hAA,8'h55,256'h0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF};
      $display("%h",data);
      my_dpi_function (data);
    end

endmodule

C++

#include <iostream>
#include <iomanip>
#include <svdpi.h>

using namespace std;

extern "C" int my_dpi_function (svLogicVecVal* data) {
    data+=8;
    cout << "# C++: ";
    for (int i=0; i<9; i++)
      cout << std::hex << std::setw(8) << std::setfill('0') << (data--)->aval;
    cout << "\n";
  return 0;
}
Matthew Taylor
  • 13,365
  • 3
  • 17
  • 44