前言
相较于Verilog,SV加入了许多不同的资料类型,接下来我就来介绍这些资料类型要怎么使用,跟Verilog有什么不同。
变数 v.s. 线
Continuous assignment: 使用assign来赋值
Procedural assignment: 在always/initial等Block当中赋值
Verilog当中大致上分为reg跟wire两种类型,要注意的是reg只能使用Procedural assignment,而wire则只能用Continuous assignment。但是在SV则划分为variables跟net-type这两种,net-type跟wire一样只能用Continuous,不一样的是variables类型可以用Continuous也可以用Procedural assignment。
Example1
module test; logic a1; logic a2; wire b; assign a2 = 1; assign b = 0; initial begin #10 a1 = 1; $display("a1 = %b",a1); $display("a2 = %b",a2); $display("b = %b",b); endendmodule
输出结果
a1 = 1, a2 = 1, b = 0
二值 v.s. 四值
Verilog提供的资料当中都是使用四值逻辑的,也就是说一笔资料里面会有0,1,x,z这四种状态,其中的x,z是用来表示电路当中不稳定的状态。而在SV当中则新增了二值逻辑,就是只有0,1两种状态,这种二值逻辑在使用上是专门给验证使用的,所以它不需要x,z这两种状态。二值逻辑使用起来会更像在写C语言,要跟C语言做对接也会更容易。
除此之外,二值跟四值逻辑是可以互相转换的,但是要注意的是当四值转二值时,原本的x,z的数值会被转换为0。
Example2
module test; bit a1 = 1'b0; bit a2 = 1'b1; logic b1 = 1'bx; logic b2 = 1'bz; initial begin $display("a1 = %b", a1); $display("a2 = %b", a2); $display("b1 = %b", b1); $display("b2 = %b", b2); $display("a1 = %b", logic'(a1)); $display("a2 = %b", logic'(a2)); $display("b1 = %b", bit'(b1)); $display("b2 = %b", bit'(b2)); endendmodule
这里用到一个转换的方式,把logic跟bit做转换
<data_type>'(value)
输出结果
a1 = 0, a2 = 1, b1 = x, b2 = z
a1 = 0, a2 = 1, b1 = 0, b2 = 0
有号数 v.s. 无号数
跟C语言一样,当我们在使用int/integer等类型时要注意是有号还是无号数。
Example3
module test; int a1 = 32'hffffffff; int a2 = 32'h7fffffff; initial begin $display("a1 = %d",a1); $display("a2 = %d",a2); end endmodule
输出结果
a1 = -1, a2 = 2147483647
位元数(bit-width)
使用时要注意每个类型的预设bit-width不一样。
Example4
module test; bit a; byte b; logic c; shortint d; int e; longint f; initial begin $display("size of a = %d",$bits(a)); $display("size of b = %d",$bits(b)); $display("size of c = %d",$bits(c)); $display("size of d = %d",$bits(d)); $display("size of e = %d",$bits(e)); $display("size of f = %d",$bits(f)); endendmodule
输出结果
a = 1, b = 8 , c = 1, d = 16, e = 32, f = 64
后记
这篇花了不少时间在写範例程式,都可以在EDA Playground上面去执行,可以自己在上面修改测试看看,记得把Simulator选择成Aldec Riviera Pro就可以Run了!