SystemVerilog学习之路(5)— 结构体、枚举类型和字符串
一、前言
在SystemVerilog中可以和C语言一样使用typedef
来创建新的类型,这样通过和结构体的配合便可以自定义我们想要的数据类型了。
二、结构体类型
在SystemVerilog中可以使用struct
创建结构体,不过struct的功能少,它只是一个数据的集合,其通常的使用方式是将若干相关的变量组合到一个struct结构定义中。编写代码如下所示,自定义一个结构体类型,并对其赋值,然后将其值打印出来。
module struct_s;
initial begin
typedef struct {int a;
byte b;
shortint c;
int d;
} my_struct_s;
my_struct_s st = '{32'haaaa_aaaa,
8'hbb,
16'hcccc,
32'hdddd_dddd};
$display("str = %x %x %x %x ", st.a, st.b, st.c, st.d);
end
endmodule
仿真运行如下所示
三、枚举类型
枚举类型创建了一种强大的变量类型,它仅限于一些特定名称的集合,例如指令中的操作码或者状态机中的状态名,规范的操作码和指令例如ADD
、WRITE
、IDLE
等有利于 代码的编写和维护,它比直接使用'h10
这样的常量使用起来可读性和可维护性更好。枚举类型enum
经常和typedef
搭配使用, 由此便于用户自定义枚举类型的共享使用。编写代码如下所示
module enumm;
typedef enum{INIT, DECODE, IDLE}fsmstate_e;
fsmstate_e pstate, nstate; // 声明自定义类型变量
initial begin
case(pstate)
IDLE: nstate = INIT; // 数据赋值
INIT: nstate = DECODE;
default:nstate = IDLE;
endcase
$display("Next state is %s", nstate.name()); // 显示状态名
end
endmodule
仿真运行如下所示
我们在对枚举类型变量赋值时必须要使用其定义类型中的值,而不能使用其他的值,例如下所示,这样的赋值时错误的
nstate = 1;
我们在编译过程中编译器会直接报错
四、字符串
SystemVerilog中的string类型可以用来保存长度可变的字符串,单个字符是byte类型,长度为N的字符串中,元素编号从0到N-1,另外需要注意的是,和C语言不一样,字符串的结尾不带标识符null,所有尝试使用字符\0
的操作都会被忽略。编写代码如下所示
module strings;
string s;
initial begin
s = "IEEE ";
$display(s.getc(0)); // 显示'I'的ASCII码值73
$display(s.tolower()); // 返回所有字符小写的字符串
s.putc(s.len()-1, "-"); // 将最后一个字符`空格`变为‘-’
s = {s, "P1800"}; // 字符串拼接
$display(s.substr(2,5)); // 提取第2到5个字符
// 创建一个临时字符串并打印出来
my_log($psprintf("%s %5d", s, 42));
end
task my_log(string message); // 打印消息
$display("@%0t: %s", $time, message);
endtask
endmodule
仿真运行如下所示