Why my DPI-C failed after using declaring C function - write()?

Hi folks,

I have some difficulty to bring up a simple DPI-C example.

The compiler error message like this:

Error-[DPI-DXCWOS] DPI export call with NULL scope
DPI export function/task “wait_clock” is illegally invoked (instead of from
an import function) from user/external C/C++ code, and thus has NULL scope.
Please check if the export function is called from an import function, or
the scope is properly set via ‘svSetScope’.

write(): addr:0x4, data:0x3e3a2000

1.Is there some wrong by declaring a function called write() in C?

2. Why test_func() didn’t invoke correctly, but write() get invoked? If there any way to add some CFLAGs to let C Compiler(gcc) to detect this type of error?

module top;  
    import "DPI-C" context task test_func();
    export "DPI-C" task wait_clock;
    
    bit clk = 0;
    always #5 clk = ~clk;

    task wait_clock();
		@(posedge clk);
    endtask

    initial begin
		int result;
		#10;
		test_func();
    end
endmodule
#include <stdio.h>
#include "svdpi.h"

extern void wait_clock(void);
extern void write(int addr, int data);
extern int test_func(void);

void write(int addr, int data) {
  printf("write(): addr:0x%0x, data:0x%0x\n", addr, data);
  //add delay to mimic the actual write on SV side
  wait_clock();
  printf("write(): complete.\n");
}

int test_func(void) {
  printf("Calling wait_clock from C...\n");
  wait_clock();
  printf("Returned from wait_clock.\n");
  return 0;
}

The same rules that prohibit a function from calling a task in SystemVerilog also apply to C routines that use the DPI. In this case, you must import test_func as a task, rather than a function.

The assignment statement result = test_func(); if the RHS consumed time.

Thank, Dave. That’s helpful. The function, task imported from C is strictly checked in SystemVerilog, but C only have function. Now the Error message sounds clear to me.

Can anyone share some insight on this issue? Thanks ahead.

I had the impression from your previous post that everything was clear to you now. What is the remaining issue?

That is fast reply, Dave. I have add another function in C side, declare write(), which is called inside test_func(). However, test_func is not invoked in the first place. Instead, write() is invoked. It seems write() is a reserved function in DPI-C. I am not sure that can be exploited to inject some unintended code. That is completely different topic.

Here I am more curious is there any way to avoid the C domain function naming, and is there any flags can be add to GCC to detect this issue ahead?

The DPI import/export syntax provides a way of mapping names between SystemVerilog and C:

import "DPI-C" context c_name=task sv_name();

You may have run into a tool specific problem. Your code runs as you expect with other tools on EDAPlayground.

It seems a tool specific problem. Only Questa can take my code as what I expected. :slight_smile: The other tools either skip it or complain an error.