一般的SystemVerilog专业书不会全方位细致的讲SV,所以过一遍Accellera的SV LRM还是很有必要的。
IEEE SV标准: IEEE 1800-2017 - IEEE Standard for SystemVerilog--Unified Hardware Design, Specification, and Verification Language
Accellera的SV LRM: SystemVerilog_3.1a Language Reference Manual
请点击图片看清晰内容,主要包含了SV新增加的feature。
cast即 显式(expelictly)的强制数据类型转换;
在编译时候做类型转换
int'(2.0 * 3.0) // real转化成int
shortint'{8'hFA,8'HC8} // concatenation,拼接表达式结果转成shortint类型
17'(x-2) //表达式结果强制改变数据宽度
signed'(x) //将x转化成有符号数
mytype'(y) //将y转化成用户自定义类型
logic [7:0] regA;
logic signed [7:0] regS;
regA = unsigned'(-4); // regA = 8'b11111100
regS = signed'(4'b1100); // regS = -4
$cast可以作为task和function来调用, 称为 dynamic casting,在运行的时候是做类型转换。
function int $cast( singular dest_var, singular source_exp );
task $cast( singular dest_var, singular source_exp );
将$cast作为一个任务来使用时,如果和目的对象类型不匹配则出现run-time error。 当$cast作为函数使用时,如果类型不兼容,$cast函数返回0,如果类型兼容则返回非零值。
可以被packed成bit流的类型可以被称作 bit-stream 类型,它包括:
-- 任何integral,packed,或string类型
--上面类型构成的unpacked的数组,结构图和class
-- 任何上面类型构成的动态数组,队列和散列
B=dest_t'(A)
将A转化成类型B需要两步:
1.先将A转化成和A的bit长度一致的packed数值。如果A有4值类型的bit field,则需要将所有bit转化为4值的。
2.将该packed数值转换成B类型。 如果B是二值类型,而packed数值是四值的,需要做4-state-->2-state的cast。
如shortreal转化成int,小数部分会丢失,如果想避免丢失信息,可以用系统函数$shortrealtobits来实现,用$bittoshortreal可无损还原。
struct类型可无损的转化成bit pattern,其中定义最靠前的field在最高位。系统函数$bits可以获取 struct的size。
packed的数据类型不需要做显式的类型转换也可。
typedef struct{
bitisfloat;
union{ inti; shortrealf; } n; // anonymous type
} tagged_st; // named structure
typedef bit[$bits(tagged_st) - 1 : 0] tagbits; // tagged_st defined above
tagged_st a [7:0]; // unpacked array of structures
tagbits t = tagbits’(a[3]); // convert structure to array of bits
a[4] = tagged_st’(t); // convert array of bits back to structure
$itor, $rtoi, $bitstoreal, $realtobits, $signed
parameterized data tyep. 只定义一种数据类型,然后利用参数产生许多不同变种。
virtual class C#(parameter type T = logic, parameter SIZE=1);
typedef logic [SIZE-1:0] t_vector;
typedef T t_array [SIZE-1:0];
typedef struct {
t_vector m0 [2*SIZE-1:0];
t_array m1;
} t_struct;
endclass
module top ();
typedef logic [7:0] t_t0;
C#(t_t0,3)::t_vector v0;
C#(t_t0,3)::t_array a0;
C#(bit,4)::t_struct s0;
endmodule
-- logic -> bit : 1 是 1; 0,x,z 均是 0.
-- 宽度不同的bit数据间转换是不会报warning的, 写代码是需要注意,不过专业的linting工具应该也能检查到。
-- small-width bits -> large-width bit : 会自动在左侧补0,
-- large-width bit->small-width bits: 会自 turcation.
typedef foo;
foo f = 10;
typedef int foo;
但枚举类型必需在定义之后使用。
enum integer {IDLE, XX='x, S1, S2}; //syntax error
enum integer {IDLE, XX='x, S1='b01, S2='b02}; //syntax correct
enum {a=0, b=7,c,d=8}; //Syntax error, c和d都是8