How to bind the DPI files and testbench files

Hi ,

I have code
tbench.sv

module tbench;
export "DPI-C" task dpisv_RegRead32;

task dpisv_RegRead32(input int unsigned offset, output int unsigned data);
    $display(" dpisv_RegRead32 %t ",$time); 
    data = 32'h1000; //data I have hardcoded but needs to be picked from SV TB
   #20;
 endtask

initial 
begin
  setup_complete();
  #1000;
  $finish();
end
endmodule //end of tbench

dpi.sv file

module reftb_dpi;
tbench tbench_i();  // instantiated the tbench

import "DPI-C" context task doTest();

  task setup_complete ();
      begin
        $display(" platform_setup_complete is called at %t ",$time); 
        doTest();
      end
  endtask
endmodule

dpi.c file

#include "svdpi.h"
#include "svdpi_src.h"
svScope g_scope;
FN_EXTERN void dpisv_RegRead32(uint32_t offset, uint32_t* data);
FN_EXTERN boolean_t RegRead32 ( unsigned offset, uint32_t * data){
    svSetScope(g_scope);
    dpisv_RegRead32(offset, data);
    return BOOLEAN_TRUE;
}

When I run a C test , which calls RegRead32 from C and inturn calls dpisv_RegRead32(…), I get error.

RegRead32 invoked with offset = 4

** Fatal: (vsim-3758) A scope context for ‘dpisv_RegRead32’ could not be found within calling context ‘reftb_dpi’.

The nearest DPI import tf up the call chain is at line 158 of file /arm/projectscratch/pd/kalari/jaydv01/kalari/validation/…/DI_val_experiments/platform/acs_ref_tb//dpi_SV//reftb_dpi.sv

Time: 100 ns Iteration: 0 Process: /reftb_dpi/acs_tbench_i/#INITIAL#109 File: validation/…/DI_val_experiments/platform/acs_ref_tb//dpi_SV//smmu_reftb_dpi.sv

Fatal error at /arm/projectscratch/pd/kalari/jaydv01/kalari/validation/…/DI_val_experiments/platform/acs_ref_tb//dpi_SV//reftb_dpi.sv line 27

HDL call sequence:

Stopped at ./DI_val_experiments/platform/smmu_acs_ref_tb//dpi_SV//smmu_reftb_dpi.sv 27

called from ./DI_val_experiments/platform/smmu_acs_ref_tb//dpi_SV//smmu_reftb_dpi.sv 158

called from /./DI_val_experiments/platform/smmu_acs_ref_tb//tbench/tbench.sv 112

Please can anyone let me know whats the mistake

The code in your dpi.c seems incomplete. Where do you set ‘g_scope’ to the scope of your target? If g_scope is null, you will get errors as you are seeing.

In reply to cgales:

I set at in dpi.c file as below

FN_EXTERN boolean_t RegRead32 ( unsigned offset, uint32_t * data){
svSetScope(g_scope);

It is not clear from the code you show how you get from doTest with no arguments to RegRead32 with arguments. You are calling svSetScope() with a null argument. You are #including “svdpi_src.h” which has long since been deprecated. A imported C task need to check the return value of exported SV tasks for disables, and return that value.

This works for me:

module tbench;
export "DPI-C" task dpisv_RegRead32;
 
task dpisv_RegRead32(input int unsigned offset, output int unsigned data);
    $display(" dpisv_RegRead32 %t ",$time); 
    data = 32'h1000; //data I have hardcoded but needs to be picked from SV TB
   #20;
 endtask
 
initial 
begin
  setup_complete();
  #1000;
  $finish();
end
endmodule //end of tbench

module reftb_dpi;
tbench tbench_i();  // instantiated the tbench
 
import "DPI-C" context task doTest(input int unsigned offset, output int unsigned data);
   int unsigned data;
   
  task setup_complete ();
      begin
        $display(" platform_setup_complete is called at %t ",$time); 
        doTest(1, data);
      end
  endtask
   endmodule // reftb_dpi

#include "svdpi.h"
#include "dpi.h"
svScope g_scope;
int doTest (uint32_t offset, uint32_t * data){
   g_scope = svGetScopeFromName("reftb_dpi.tbench_i");
   svSetScope(g_scope);
   return dpisv_RegRead32(offset, data);
 }

Also, we recommend compiling with -dpiheader dpi.h and include’ing that file to make sure a compile time that your prototypes match instead of getting a run time fatal.