var struct { // 通过var进行结构体变量声明
logic [31:0] a, b;
logic [ 7:0] opcode;
} Instruction_Word_var;
wire struct {
//结构体线网声明,定义为线网类型时,结构体的所有成员必须都是四态类型的
logic [31:0] a, b;
logic [ 7:0] opcode;
} Instruction_Word_net;
typedef struct { //结构体定义,不分配存储器
logic [31:0] a, b;
logic [ 7:0] opcode;
logic [23:0] address;
} instruction_word_t;
instruction_word_t IW; // 结构体实例化时分配存储区
instruction_word_t IW = ’{100, 3, 8’hFF, 0}; //赋值a=100 b=3 opcode=FF address=0
IW.a = 100; //引用结构体成员的名称对成员进行赋值
if(!resetN) IW = ’{100, 5, 8’hFF, 0}; //同初始化的时候类似,但这是在过程块中进行的
W = ’{ real:1.0, default:0, r1:3.1415 };
//r1=3.1415 其他real成员=1.0 其他成员=0 (precedence:显性成员名赋值>指定数据类型赋值>default)
默认情况下,结构体是非压缩的。结构体成员是独立的变量或常量。
使用packed显示的声明一个压缩结构体。压缩结构体按照指定的顺序以相邻的位来存储结构体成员。压缩结构体被当做一个向量存储,结构体的第一个成员在向量的最左边。向量的最低位是结构体最后一个成员最低位,其位编号为bit 0。如图所示(类似小端模式):
struct packed {
logic valid;
logic [ 7:0] tag;
logic [31:0] data;
} data_word;
packed structure的成员可以通过成员名引用(
. )也可以使用结构体向量的相应位来引用( [M:N])。
题外话:
- real和shortreal分别对应C语言的双精度和单精度,不可被综合,但是在抽象硬件模型和tb中有用,因此不算做整数范畴
- 压缩结构体可被看作是向量来操作。(除了’{}赋值操作是当做unpacked以外)
typedef struct packed {
logic [15:0] source_address;
logic [15:0] destination_address;
logic [23:0] data;
logic [ 7:0] opcode;
} data_packet_t;
union packed {
data_packet_t packet; //压缩结构体
logic [7:0][7:0] bytes; // 压缩数组
} dreg;
变量及线网均可以用于数组。
声明:
verilog一次只能访问数组的一个元素。
数组中各个元素存储位置相互独立
需指定起始地址及结束地址 eg.int array [64:83]; //地址从64-83的Verilog数组
增加event数据类型及所有SV数据类型
SV可以引用整个非压缩数组以及一段元素(复制非压缩数组时”=”左右需同样结构及类型)
无需指定起始位置及结束位置,只需指定维度大小
logic [31:0] data [1024]; //is equivalent to logic [31:0] data [0:1023];
logic [3:0][7:0] data; // 2-D packed array包含4个8位的子数组
logic [3:0][7:0] data; // 2-D packed array 4个8位数组
wire [31:0] out = data; // whole array
wire sign = data[3][7]; // 一位
wire [3:0] nib = data [0][3:0]; // 一部分
byte high_byte;
assign high_byte = data[3]; // 8-bit 宽的一段
logic [15:0] word;
assign word = data[1:0]; // 2段
logic [3:0][7:0] a = 32’h0; //向量赋值
logic [3:0][7:0] b = {16’hz,16’h0}; //常数的拼接
logic [3:0][7:0] c = {16{2’b01}}; //常数的复制(16个01)
typedef int data_t [3:0][7:0]; // unpacked type
data_t a; // unpacked array
int b [1:0][3:0][3:0]; // unpacked array
a = data_t’(b); // 将非压缩数组赋给不同结构的非压缩数组
wire [3:0][7:0] data [0:1023]; //由32位元素组成的非压缩数组,每个元素是由4个字节组成的压缩数组
foreach循环用来对一维或多维数组中的元素进行迭代,而不必指定数组每个维度的宽度
int sum [1:8] [1:3];
foreach ( sum[i,j] ) //自变量是数组名,[ ]中用,隔开循环变量列表。
sum[i][j] = i + j; //对数组初始化
$dimensions(array_name) //返回数组的维数
$left(array_name, dimension) //返回指定维度的最高有效位(MSB)
logic [1:2][7:0] word [0:3][4:1];
$left(word,1) //will return 0
$left(word,2) //will return 4
$left(word,3) //will return 1
$left(word,4) //will return 7
$right(array_name, dimension) //返回指定维度的最低有效位(LSB)
$low(array_name, dimension) //返回指定维度的最低位数(上例中dimension1-4分别 对应0,1,1,0)
$high(array_name, dimension) //返回指定维度的最高位数
$size(array_name, dimension) //返回指定维度元素的总个数(high-low+1)
$increment(array_name, dimension) //对于指定的维度,如果$left>=$right,返回1,否则-1
$bit(expression) //返回表达式的位数
bit [63:0] a; logic [63:0] b;
$bits(a) returns 64;
$bits(b) returns 64;