在systemverilog中,casting意味着把一种数据类型转化为另一种数据类型。在一个变量赋值时,需要左右两边的值是一样的数据类型。在一些情况下,我们需要为不用数据类型的变量赋值,此时就需要类型转换,否则编译器会报错。在systemverilog中有两种类型的数据转换:
静态的casting
动态的casting
静态转换具有如下特点:
静态转换不适合面向对象编程
将一种数据类型转换为另一种数据类型(如string转化为int)
静态也意味着转换的数据类型是固定的
会在编译的时候检查是否可行
形式上我们可以使用单引号(')表示类型转换,转换对象要用圆括号包起来。
如下面的例子所示:
module casting;
real r_a ;
int i_a ;
initial begin
r_a = (2.1 * 3.2);
//real to integer conversion
i_a = int'(2.1 * 3.2); // or i_a = int'(r_a)
$display("real value is %f", r_a);
$display("int value is %d", i_a);
end
endmodule
其输出结果是:
由此看出当把real类型数据转化为Int类型数据时,会进行四舍五入。
动态转换具有如下特点:
在继承树中,我们把一个孩子类的变量赋值给父类变量是合理的。
paraent_class = child_class; // allowed
但是若把一个父类的变量赋值给一个子类的变量是不被允许的。如下所示:
child_class = parent_class; //not allowed
据如下例子:
class parent_class;
bit [31:0] addr;
function display();
$display("Addr = %0d", addr);
endfunction
endclass
class child_class extends parent_class;
bit [31:0] data;
function display();
super.display();
$display("Data = %0d", data);
endfunction
endclass
module inheritence;
initial begin
parent_class p = new();
child_class c = new();
c.addr = 10;
c.data = 20;
p = c; // assigning child class handle to parent class handle
c.display();
end
endmodule
其输出结果是:
做如下修改,把父类的句柄赋值子类的句柄。
编译器会报如下的错误:
做如下修改,创建一个子类的句柄c1。
但是编译器仍然会报错:
做如下改动,可以实现父类的句柄转化为子类的句柄。
其输出结果是:
在systemverilog中,我们想隐藏类中一些数据,这些数据只可以通过一些方法才可以被访问到。这种技术就叫做封装。因为它把一些数据隐藏一起,只可以被信得过的使用者(类中定义的方法)才可以访问。
这种实现方式就是通过对访问权限的控制。默认的情况下,任何都可以同时这个对象的句柄来访问类中的成员和方法,但是在一些情况下,这会危害类中成员的值。类中成员的权限是通过在类成员名字的前面加图两个关键字:local和protected
本地类成员不允许在类外访问成员变量,也就是要通过类的方法才可以访问到,任何的违例都会导致编译器报错。其声明形式如下:
local integer x;
如下的例子所示:
从而会导致编译器报错:
确实需要修改tmp_addr值时,new方法可以传递参数,但只在创建对象时执行一次。需要再修改,我们就需要定义新的方法用于给tmp_addr设置值。
我们再来保护类型成员,在某些用例中,只需要通过派生类访问类成员,这可以通过在类成员前面加上 protected 关键字来完成。即子类可以在类外访问protected类型变量,而其它类却是不可以的。
class parent_class;
protected bit [31:0] tmp_addr;
function new(bit [31:0] r_addr);
tmp_addr = r_addr + 10;
endfunction
function display();
$display("tmp_addr = %0d", tmp_addr);
endfunction
endclass
class child_class extends parent_class;
function new(bit [31:0] r_addr);
super.new(r_addr);
endfunction
function void incr_addr();
tmp_addr++;
endfunction
endclass
//module
module encapsulation;
initial begin
parent_class p_c = new(5);
child_class c_c = new(10);
//varible declared as protected cannot be accessed outside the class
p_c.tmp_addr = 10;
p_c.display();
c_c.incr_addr(); // Accessing protected varible in extended class
c_c.display();
end
endmodule
在编译器报错如下:
注释掉下面这一句:
结果是: