A customer wanted me to post my example to this forum:
From: ramnararyan [mailto:ramnarayan@xxxxxxxx]
Hi,
I got information from cdnuser forum that u have example code of the dpi import/export declarations, and the export function inside the interface, and you were able to access the import function from both modules attached to the interface. so i would like to adopt this methodology.I m using NCSIM 6.2.
please send me example.
-----------------
so here is the example. This example has more than the orginal request, it also shows how to pass a queue of class thru an interface, as well as how to access DPI inside an interface:
-----file: class_across_interface.sv---------------
// Todd Mackett Cadence Design Systems
// irun class_across_interface.sv dpi.c
// tested with IUS5.83s1 and IUS6.2s1
/*
top--------------------------
| test --->interface---->dut |
|-----------------------------
*/
package mypack;
class some_class;
int some_int;
real some_real;
protected string some_string; // needs to be protected for IUS5.83
function void set_data (int i, real r, string s);
some_int =i;
some_real = r;
some_string = s;
endfunction
task get_data(output int i, output real r, output string s);
i = some_int;
r = some_real;
s = some_string;
endtask
function void print_data();
$display("Int: %d, Real: %f, String: %s", some_int, some_real, some_string);
endfunction
endclass
endpackage
// ------
// This channel is an interface that is a queue of classes
interface myIF;
import mypack::*;
// -----dpi------
import "DPI-C" context c_func = function int my_c_func (input int a);
export "DPI-C" sv_func = function my_sv_func;
function int my_sv_func(input int a);
return a + 2;
endfunction
// -----end dpi-----
event some_event;
some_class some_classQ[$]
function int some_classQ_size();
return some_classQ.size();
endfunction
task push_class_in_Q(input some_class Qin);
some_classQ.push_front(Qin);
endtask
task pop_class_out_Q(output some_class Qout);
Qout = some_classQ.pop_back();
endtask
endinterface
// -----------------
module top();
int top_int;
reg clk = 'b1;
initial
forever clk = #10 ~clk; // system clk
myIF myIFi(); // instantiate interface
test testi(clk, myIFi);
dut duti(clk, myIFi);
endmodule
// --------------
// The test module create a class of information and puts it in the
// channel (a queue in the interface)
module test (input clk, myIF myIFi);
import mypack::*;
int i;
real r;
string s;
initial
#200 $finish;
some_class top_class;
always @(posedge clk)
begin
top_class = new;
i = $urandom_range(5,1);
randcase
1: r = 3.14;
1: r = 123.456;
1: r = -943.825;
endcase
randcase
1: s = "IUS SystemVerilog";
1: s = "Cadence";
1: s = "Who needs VHDL?";
endcase
// dpi call inside interface:
$display("DPI Call %d", myIFi.my_c_func(30));
top_class.set_data(i, r, s); // set the values into class
myIFi.push_class_in_Q(top_class); // transmit the class
-> myIFi.some_event; // cause the event
end
endmodule
// The dut module consumes the class when the event is valid
// and displays its contents as it comes across the interface
module dut (input clk, myIF myIFi);
import mypack::*;
some_class dut_class =new;
always @(myIFi.some_event) // process event
begin
$display("\nQueue Size %d",myIFi.some_classQ_size() );
myIFi.pop_class_out_Q(dut_class);
dut_class.print_data();
// dpi call inside interface:
$display("DPI Call %d", myIFi.my_c_func(997));
end
endmodule
-------------end file: class_across_interface.sv---------------
----file: dpi.c--------
#include "dpi.h"
//extern int sv_func(int a);
int c_func(int a) {
return sv_func(a);
}
-----end file: dpi.c---------
----partial irun.log file:--------
Queue Size 1
Int: 1, Real: 3.140000, String: Who needs VHDL?
DPI Call 999
DPI Call 32
... ... ...
|