将 "type" 参数传递给函数
Passing "type" argument to functions
是否可以将 type
参数传递给函数,以便 create_eclass*
函数只能通过传递 class 类型参数来编写一次?
class bclass;
virtual function void print();
$display("Base Class");
endfunction
endclass
class eclass1 extends bclass;
function void print();
$display("Extended Class1");
endfunction
endclass
class eclass2 extends bclass;
function void print();
$display("Extended Class2");
endfunction
endclass
program Test ;
bclass q[$];
function create_eclass1();
bclass b;
eclass1 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
function create_eclass2();
bclass b;
eclass2 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
initial
begin
create_eclass1();
create_eclass2();
foreach(q[i]) q[i].print();
end
endprogram
是的,您可以通过创建一个对象来完成此操作,该对象充当您要创建的类型的代理。这种代码模式在UVM工厂中使用。
typedef bclass; // this would be uvm_object in the UVM
interface class object_wrapper; // like a virtual class except it only contains pure virtual methods
pure virtual function bclass create;
endclass
class object_registry#(type T) implements object_wrapper;
typedef object_registry#(T) this_type;
local static this_type _singleton; // only one object for each class type
local function new;
endfunction
static function object_wrapper get;
if (_singleton == null) _singleton = new;
return _singleton;
endfunction // if
virtual function T create;
create = new;
endfunction
endclass
此代码的其余部分与原始示例中的代码基本相同。我刚刚通过添加导致 object_registry 中的静态变量和方法存在的 typedef 注册了 类。
class bclass;
virtual function void print();
$display("Base Class");
endfunction
endclass
class eclass1 extends bclass;
typedef object_registry#(eclass1) type_id;
function void print();
$display("Extended Class1");
endfunction
endclass
class eclass2 extends bclass;
typedef object_registry#(eclass2) type_id;
function void print();
$display("Extended Class2");
endfunction
endclass
module Test ;
bclass q[$];
function void create_eclass(object_wrapper h);
q.push_back(h.create());
endfunction
object_wrapper a1,a2;
initial
begin
create_eclass(eclass1::type_id::get() );
create_eclass(eclass2::type_id::get() );
// or another way -
a1 = eclass1::type_id::get();
a2 = eclass2::type_id::get();
create_eclass(a1 );
create_eclass(a2 );
create_eclass(a2 );
create_eclass(a1 );
foreach(q[i]) q[i].print();
end
endmodule
我有 a paper 详细解释了这个工厂模式代码。
我的一位同事提出的解决方案与 Dave 的建议类似。
virtual class eclass_creator #( type T = bclass );
static function T create(int k) ;
create = new(k) ;
endfunction
endclass
这允许创建作用域构造函数。
class bclass;
int i;
function new(int k);
i=k;
endfunction
virtual function void print();
$display("Base Class %0d",i);
endfunction
endclass
class eclass1 extends bclass;
function new(int k);
super.new(k);
endfunction
function void print();
$display("Extended Class1 %0d",i);
endfunction
endclass
class eclass2 extends bclass;
function new(int k);
super.new(k);
endfunction
function void print();
$display("Extended Class2 %0d",i);
endfunction
endclass
program Test ;
bclass q[$];
function void push(bclass inclass);
q.push_back(inclass);
endfunction
initial
begin
push(eclass_creator #(eclass1)::create(5));
push(eclass_creator #(eclass2)::create(10));
foreach(q[i]) q[i].print();
end
endprogram
是否可以将 type
参数传递给函数,以便 create_eclass*
函数只能通过传递 class 类型参数来编写一次?
class bclass;
virtual function void print();
$display("Base Class");
endfunction
endclass
class eclass1 extends bclass;
function void print();
$display("Extended Class1");
endfunction
endclass
class eclass2 extends bclass;
function void print();
$display("Extended Class2");
endfunction
endclass
program Test ;
bclass q[$];
function create_eclass1();
bclass b;
eclass1 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
function create_eclass2();
bclass b;
eclass2 e;
e=new();
$cast(b,e);
q.push_back(e);
endfunction
initial
begin
create_eclass1();
create_eclass2();
foreach(q[i]) q[i].print();
end
endprogram
是的,您可以通过创建一个对象来完成此操作,该对象充当您要创建的类型的代理。这种代码模式在UVM工厂中使用。
typedef bclass; // this would be uvm_object in the UVM
interface class object_wrapper; // like a virtual class except it only contains pure virtual methods
pure virtual function bclass create;
endclass
class object_registry#(type T) implements object_wrapper;
typedef object_registry#(T) this_type;
local static this_type _singleton; // only one object for each class type
local function new;
endfunction
static function object_wrapper get;
if (_singleton == null) _singleton = new;
return _singleton;
endfunction // if
virtual function T create;
create = new;
endfunction
endclass
此代码的其余部分与原始示例中的代码基本相同。我刚刚通过添加导致 object_registry 中的静态变量和方法存在的 typedef 注册了 类。
class bclass;
virtual function void print();
$display("Base Class");
endfunction
endclass
class eclass1 extends bclass;
typedef object_registry#(eclass1) type_id;
function void print();
$display("Extended Class1");
endfunction
endclass
class eclass2 extends bclass;
typedef object_registry#(eclass2) type_id;
function void print();
$display("Extended Class2");
endfunction
endclass
module Test ;
bclass q[$];
function void create_eclass(object_wrapper h);
q.push_back(h.create());
endfunction
object_wrapper a1,a2;
initial
begin
create_eclass(eclass1::type_id::get() );
create_eclass(eclass2::type_id::get() );
// or another way -
a1 = eclass1::type_id::get();
a2 = eclass2::type_id::get();
create_eclass(a1 );
create_eclass(a2 );
create_eclass(a2 );
create_eclass(a1 );
foreach(q[i]) q[i].print();
end
endmodule
我有 a paper 详细解释了这个工厂模式代码。
我的一位同事提出的解决方案与 Dave 的建议类似。
virtual class eclass_creator #( type T = bclass );
static function T create(int k) ;
create = new(k) ;
endfunction
endclass
这允许创建作用域构造函数。
class bclass;
int i;
function new(int k);
i=k;
endfunction
virtual function void print();
$display("Base Class %0d",i);
endfunction
endclass
class eclass1 extends bclass;
function new(int k);
super.new(k);
endfunction
function void print();
$display("Extended Class1 %0d",i);
endfunction
endclass
class eclass2 extends bclass;
function new(int k);
super.new(k);
endfunction
function void print();
$display("Extended Class2 %0d",i);
endfunction
endclass
program Test ;
bclass q[$];
function void push(bclass inclass);
q.push_back(inclass);
endfunction
initial
begin
push(eclass_creator #(eclass1)::create(5));
push(eclass_creator #(eclass2)::create(10));
foreach(q[i]) q[i].print();
end
endprogram