SystemVerilog中常见数据类型介绍
一、常见数据类型
1)bit byte(8) int(32) shortint(16) longint(64)变量类型;
2)logic 定义变量,四态0 1 Z X,代替reg,wire;
3)void类型表示无存储;
4)var关键字表示对象是一个变量,比如 var logic[7:0] a;
5)静态变量 static 自动变量 automatic
6)用户使用typedef自定义类型
7)枚举数据类型 enum
二、枚举类型enum的使用
module FSM(input logic clock, resetN,
output logic [3:0] control);
enum logic[2:0] {WAITE=3’b001,LOAD=3’b010,
READY=3’b100} State, Next;
always @(posedge clock, negedge resetN)
if(!resetN) State <= WAITE;
else State <= Next;
always_comb begin
$display(“\n Current state is %s (%b)”, State.name, State);
case (State)
WAITE: Next = LOAD;
LOAD: Next = READY;
READY: Next = WAITE;
endcase
$display(“Next state will be %s (%b)”, Next.name,Next);
end
assign control = State;
endmodule
三、结构体struct的介绍
结构体struct一种变量集表示,它可以包括任何数据类型,可以集合不同类型和大小的变量、常量、自定义类型:
定义结构体
struct {
int a,b;
opcode_t opcode; //用户自己定义类型
logic [23:0] address;
bit error;
} Instruction_Word (结构体名);
instruction_word_t IW
引用结构体:
<结构体名>.<变量名>,如:
Instruction_Word.address;
结构体赋值:
instruction_word_t IW = ’{100,3,8’hff,0};
always @()
IW.a = 100; IW.b = 5; IW.opcode = 8’hff; IW.address=0;
四、联合体union介绍
联合体union数据类型,和struct差不多,但是在内存分配机制上有些不同,union能够减少存储。
定义联合体
typedef union {
int a;
int unsigned u;
} data_t (联合体名);
data_t data;
引用联合体:
<联合体名>.<变量名>
比如data.a;
五、struct和union的使用
package
package definitions;
typedef enum {ADD,SUB,MULT,DIV,SL,SR} opcode_t;
typedef enum {UNSIGNED, SIGNED} operand_type_t;
typedef union packed { logic[31:0] u_data;
logic signed [31:0] s_data; } data_t;
typedef struct packed {
opcode_t opc;
operand_type_t op_type;
data_t op_a;
data_t op_b; } instr_t;
endpackage
struct packed表示压缩结构体,当做向量存储结构体成员。
RTL
import definitions:: *;
module instruction_register(
output instr_t[0:31] instr_reg,
input data_t operand_a,
input data_t operand_b,
input operand_type_t op_type,
input opcode_t opcode,
input logic[4:0] write_pointer );
always @(write_pointer) begin
instr_reg[write_pointer].op_type = op_type;
instr_reg[write_pointer].opc = opcode;
if(op_type ==SIGNED) begin
instr_reg[write_pointer].op_a.s_data = operand_a.s_data;
instr_reg[write_pointer].op_b.s_data = operand_b.s_data; end
else begin
instr_reg[write_pointer].op_a.u_data = operand_a.u_data;
instr_reg[write_pointer].op_b.u_data = operand_b.u_data; end
end
endmodule
testbench
import definitions:: *;
module tb_instruction_register();
instr_t[0:31] instr_reg;
data_t operand_a=32'h0,operand_b=32'h0;
operand_type_t op_type = UNSIGNED;
opcode_t opcode = ADD;
logic[4:0] write_pointer = 5'd0;
logic clock = 1'b0;
always #2 clock = ~clock;
always_ff@(posedge clock)
begin
operand_a = {$random}%32;
operand_b = {$random}%32;
if(write_pointer <= 5'h1f)
write_pointer += 1'b1;
else
write_pointer = 5'd0;
if(write_pointer > 5'h0f)
opcode = SUB;
else
opcode = ADD;
end
instruction_register n1(
instr_reg,
operand_a,
operand_b,
op_type,
opcode,
write_pointer );
endmodule