In DPI-C, what data types to be used for internal variables?

4.9k views Asked by At

I am not getting correct output for the following piece of code using DPI-C in VCS in EDA Playground. I expect 6 as answer but I get 248 every time, irrespective of a and b values. I have tried using svLogic, int and unsigned char for data type for a_int in helloFromC.c.

module automatic test;

  import "DPI-C" function void helloFromC(logic [2:0] a, logic [2:0] b);

  initial run();

  task run();
    logic [2:0] a; 
    logic [2:0] b; 
    logic [2:0] c;
    a = 3'b100;
    b = 3'b010;
    c = a+b;
    $display("Output from SV is %0d", c);
    helloFromC(a,b);

  endtask

endmodule

This is my C program

#include <stdio.h>
#include <svdpi.h>


extern "C" int helloFromC(svLogic a, svLogic b) {
  svLogic a_int = a+b;
  printf("Output from C is %d", a_int);
  return 0;
}

I get output as

Output from SV is 6
Output from C is 248
2

There are 2 answers

3
Greg On BEST ANSWER

svLogic is supposed to map to a single bit logic. You have a vector (aka packed array), therefor you should be using svLogicVecVal. It is still a 4-state value, so algorithmic operations of SystemVerilog values performed on the C side may not work the way you expect. Using bit [2:0] on the SystemVerilog side and svBitVecVal on the C side will work more as you expect. Or simplify things and use int on both sides.

For more on DPI, refer to IEEE1800-2012 section 35, Annex H, and Annex I.

1
Shankhadeep Mukerji On

From one of the links, addition using DPI callI could find what I was looking for

#include <stdio.h>
#include <svdpi.h>


extern "C" void
add_bpv(
    const svBitVecVal* a,
    const svBitVecVal* b,
    svBitVecVal* c) {
    *c = *a + *b;
    printf("Output from C is %d", *c);
}

And now the SV program DPI call

module automatic test;

  import "DPI-C" function void add_bpv(input bit [3:0] a,b, output bit [3:0] c);

  initial run();

  task run();
    bit [3:0] a,b,c;
    a = 3'b100;
    b = 3'b010;
    c = a+b;
    $display("Output from SV is %d", c);
    add_bpv(a,b,c);
  endtask

endmodule

The output is what I wanted

Output from SV is  6
Output from C is 6