Logic的引入背景
相比于verilog将仍和net区分的如此清楚,在sv中新引入了一个数据类型logic,他们的区别和联系在于:
1、 verilog作为硬件描述语言,倾向于设计人员自身懂得所描述的电路中那些变量应该被视为寄存器,而那些变量被视为线网(wire),这不但有利于后端综合工具综合,也便于阅读和理解。
2、 sv(verilog3.0)作为侧重于验证的语言,并不十分关心logic对应的逻辑应该被综合为寄存器还是线网,因为logic被使用的环境是验证环境,logic只会作为单纯的变量进行赋值操作,而这些变量也只属于软件环境构建。
3、 logic被推出的另外一个原因也是为了方便验证人员驱动和连接硬件模块,而省去考虑究竟该使用reg还是wire的精力、节省时间的同时也避免了出错的可能。
bit
与logic对应的是bit类型,他们均可建立矢量类型(vector),区别在于:
i)logic为四值逻辑,0、1、x(不确定)、z(高阻态,不受驱动)
ii)bit为二值逻辑,只可为0、1
一些要点
1、sv为何在四值逻辑的基础上还要引入二值逻辑?
因为sv在一开始被设计的时候,就期望将硬件的世界与软件的世界分离开,硬件的世界指的就是硬件设计,所以四值逻辑属于硬件逻辑,而软件的世界即验证环境,更多的是二值逻辑。
2、常见的四值逻辑与二值逻辑
四值逻辑:integer、logic、reg、net-type(例如wire、tri)
二值逻辑:bit、byte、shortint、int、longint (注意区分interger和int、integer表示32位的四值逻辑,名字越长表示四值逻辑,而且integer的初始化值为:x)
3、常见的有符号和无符号类型
有符号:byte、shortint、int、longint、integer
无符号:bit、logic、reg、net-type
exp1:
logic [7:0] logic_vec=8’b1000_0000;
logic [7:0] logic_vec=8'b1000_0000;
bit [7:0] bit_vec=8'b1000_0000;
byte signed_vec=8'b1000_0000;
initial begin
$display("logic_vec=%d",logic_vec);
$display( "bit_vec=%d",bit_vec);
$display("signed_vec=%d",signed_vec);
$stop();
end
猜一下运行结果是多少?
在遇到这些变量类型时,应注意他们的逻辑类型和符号类型,因为在变量运算中,应该尽量避免两种不一致的变量的进行操作,进而导致意外的错误!
exp2:
byte signed_vec=8'b1000_0000; //有符号的8位数
bit [8:0]result_vec; //无符号的9位数
initial begin
result_vec = signed_vec;
#10;
$display("@1 result_vec= 'h%x",result_vec);
#20;
result_vec=unsigned'(signed_vec); //转为无符号数
$display("@2 result_vec= 'h%x",result_vec);
$stop();
end
运行结果为:
有符号数signed_vec转为无符号数,首先是用自己的符号位拓宽一位,变为:9’b1_1000_0000。
在编码时,一定要注意操作符左右两侧的符号类型保持一致,如果不一致,首先将其转换为同一类型再进行运算。
对于转换方式,分为静态转换和动态转换,静态转换即在需要转换的表达式前加上单引号“`”即可,仅在编译时完成检查,该方式并不会对转换值做检查,如果转换失败也无从得知。动态转换$cast(tgt,src)在仿真转换过程中检查。
静态转换和动态转换均需要操作符号或系统函数介入,统称为显式转换(expilicit transfer)。而不需要进行转换的一些操作,称为隐式转换(implicit transfer)
exp3:
logic [3:0] x_vec=4'b111x; //四值逻辑
bit [2:0] b_vec; //二值逻辑
//隐式转换
initial begin
$display("@1 x_vec='b%b",x_vec);
b_vec=x_vec;
$display("@2 b_vec='b%b",b_vec);
$stop;
end
运行结果:
首先“111x”会截掉高位,x四值逻辑会转化为二值逻辑,关键在于x,x变为0