SV DPI; accessing a task within a module in the C code

In reply to jolup:

By complete skeleton I meant something I could run, like this:

module axi4lite_mst_c_skel;
   export "DPI-C" task axi_rd;
 
   import "DPI-C" context task read_register();
 
   task rreg;
      read_register();
   endtask 

   task axi_rd(
    input int  useraddr,
    output int userdata);
      #10; //consume time
      userdata = $urandom;
      $display("@%10t :  Read Done  [ADDR = %08h, DATA = %8h]", $time, 
                                 useraddr, userdata);
   endtask : axi_rd
endmodule : axi4lite_mst_c_skel

module top;
   
   axi4lite_mst_c_skel bus_mstr_c();
   
      initial repeat(10)
	begin
	   bus_mstr_c.rreg;
  	   bus_mstr_c.read_register; // this works too - no wrapper needed
           #500; // read every 
	end
endmodule
#include < stdio.h>
#include "svdpi.h"
#include "axi_rd.h"
extern int axi_rd(int, int*); // the SV task
 
int read_register(void)
{
  int status;
  int axidata;
  status = axi_rd(0x0, &axidata);
  printf("Data from C code: 0x%8X\r\n",axidata);
  return status;
}

There were a few problems with your original C code.

The second argument to axi_rd is an output, so its type needs to be
int*
. The actual argument you need to pass is
&axidata
. Another issue is all DPI C tasks have an
int
return type. A non-zero return status indicated there was a disabled or killed process in the call chain.

You would have caught these problems with an automatically generated header file that gets #included into your C file. (vlog -dpiheader).