You need to define your class in a module or extend it in module to have hierarchical references. If you can explain more of what you ultimately want to do, we will be better able to make a suggestion.
I need this function because I am re-constructing a verification environment. There are already some modules in physical behavior and link layer. I just want to use the tasks of these existing modules. I don’t want to write physical behavior model in SystemVerilog again.
But I just implement the higher level of a protocol, just use the existing module tasks to do lower level things. and i want to implement a package to reuse. When this package is used, the existing module also must be instantiated.
But only Mentor Questasim can support such function. Neither of Cadence IUS and Synopsys VCS can support such function. If I want use this module tasks in IUS/VCS, I must split the existing module, and use virtual interface to rewrite the behaviors again, it is really a hard work.
Maybe user defined PLI/VPI tasks can also support this function, but I am not able to write PLI tasks right now, and I do not have time to learn it now.
Thanks for your help.
It is really helpful to me. I can achieve what I want now.
By the way, the example given by that post can not work in VCS/IUS simulator either.
It can only work in questasim.
The error is the statement below:
localparam string PATH = $psprintf(“%m”);
typedef ovm_object_registery #(, PATH) …
PATH should not used in the context. Cause PATH is not know when anounce typedef.
This is a very educational thread but I’m not sure it answer the main question of the thread: how can I can call Verilog task or function from SystemVerliog class?
The referenced document show how to access the DUT PIN I/F from system Verilog class, but it not show how to call Verilog Task from System Verilog class.
assume that I have memory DUT with task recalc_ecc
module mem(…)
task recalc_ecc();
…
endtask:
endmodule
and I want to create a reusable solution that will allow me to call this task or function from a verilog class (e.g. uvm_driver) is it possible?
[EDIT]: Found a solution based on Dave’s article.
module mem();
function void print();
$display($psprintf("%m"));
endfunction : print
endmodule
module dut();
mem mem0();
mem mem1();
mem mem2();
endmodule
`include "uvm_pkg.sv"
package mem_pkg;
import uvm_pkg::*;
virtual class mem_abstract extends uvm_object;
function new(string name="");
super.new(name);
endfunction
pure virtual function void print();
endclass
endpackage
interface mem_if();
import uvm_pkg::*;
import mem_pkg::*;
localparam string PATH = $psprintf("%m");
class mem_access extends mem_abstract;
typedef uvm_object_registry #(mem_access,PATH) type_id;
static function type_id get_type();
return type_id::get();
endfunction
function new(string name="");
super.new(name);
endfunction
function void print();
mem.print();
endfunction
endclass
endinterface
import uvm_pkg::*;
import mem_pkg::*;
class test extends uvm_test;
`uvm_component_utils(test)
mem_abstract mem_access_i[3];
function new(string name="",uvm_component parent=null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
foreach (mem_access_i[i])
$cast (mem_access_i[i], uvm_factory::get().create_object_by_name($psprintf("top.dut_i.mem%0d.bind_mem_if", i)));
endfunction : build_phase
task run_phase(uvm_phase phase);
foreach (mem_access_i[i])
mem_access_i[i].print();
endtask : run_phase
endclass
module top();
dut dut_i();
bind mem mem_if bind_mem_if();
initial run_test("test");
endmodule