SV结构体学习

文章详细介绍了Verilog语言中如何使用struct创建新类型,非合并数组与合并数组的区别,以及如何通过typedef将struct定义为类型。重点讨论了赋值方式、打印函数和合并数组的使用技巧。
摘要由CSDN通过智能技术生成

学习内容来源于芯片验证小白跟随路桑做SV练习——2203期

1. 使用struct创建新类型

module tb;
	struct {
		byte unsigned r;
		byte unsigned g;
		byte unsigned b;
		} pixel_a, pixel_b, pixel_c;

	initial begin
		pixel_a = '{8'h12, 8'h24, 8'h36};
		print_pixel('{pixel_a.r, pixel_a.g, pixel_a.b})
	end
	
	function void print_pixel(byte unsigned pix_arr[3]);
		$display("r = %0x, g = %0x, b = %0x", pix_arr[0], pix_arr[1], pix_arr[2]);//%x是十六进制
	endfunction

endmodule

这段代码中,我们声明了一个结构体

struct {
byte unsigned r;
byte unsigned g;
byte unsigned b;
} pixel_a, pixel_b, pixel_c;

默认情况下,结构体是一个非合并数组,所以我们在给结构体赋值时要用 '{ }

pixel_a = '{8’h12, 8’h24, 8’h36};

我们定义了一个打印函数print_pixel,形式参数为一个数组pix_arr[3],数组内有三个元素,每个元素为无符号byte。

function void print_pixel(byte unsigned pix_arr[3]);

我们传入了我们定义的非合并数组’{pixel_a.r, pixel_a.g, pixel_a.b},通过打印函数进行打印

print_pixel('{pixel_a.r, pixel_a.g, pixel_a.b})

以下代码是错误示例

module tb;
	struct {
		byte unsigned r;
		byte unsigned g;
		byte unsigned b;
		} pixel_a, pixel_b, pixel_c;

	initial begin
		pixel_a = '{8'h12, 8'h24, 8'h36};
		print_pixel(pixel_a)
	end
	
	//情况一:
	function void print_pixel(byte unsigned pixel_a);
		$display("r = %0x, g = %0x, b = %0x", pixel_a.r, pixel_a.g, pixel_a.b);//%x是十六进制
	endfunction
	
	//情况二:
	function void print_pixel(pixel_a);
		$display("r = %0x, g = %0x, b = %0x", pixel_a.r, pixel_a.g, pixel_a.b);//%x是十六进制
	endfunction
endmodule

对于情况一:function void print_pixel(byte unsigned pixel_a);传入的形式参数为byte unsigned pixel_a,该参数实际上是一个无符号byte类型,变量名pixel_a与外面定义的结构体pixel_a是没有关系的。

对于情况二:function void print_pixel(pixel_a);传入的形式参数为pixel_a,该参数是一个变量,但是函数需要传递的是一个类型,同样,变量名pixel_a与外面定义的结构体pixel_a是没有关系的,不能指代pixel_a结构体类型

2. 结构体的赋值方式

module tb;
	struct {
		byte unsigned r;
		byte unsigned g;
		byte unsigned b;
		} pixel_a, pixel_b, pixel_c;

	initial begin
		pixel_a = '{8'h12, 8'h24, 8'h36};
		print_pixel('{pixel_a.r, pixel_a.g, pixel_a.b})
		pixel_b = pixel_a;
		print_pixel('{pixel_b.r, pixel_b.g, pixel_b.b})
		pixel_b = '{g:8'haa, b:8'hbb, r:8'hcc};
		print_pixel('{pixel_b.r, pixel_b.g, pixel_b.b})//通过索引赋值
	end
	
	function void print_pixel(byte unsigned pix_arr[3]);
		$display("r = %0x, g = %0x, b = %0x", pix_arr[0], pix_arr[1], pix_arr[2]);//%x是十六进制
	endfunction

endmodule

3. 合并数组

结构体默认是非合并形的,添加packed后会变为合并形。合并形与非合并形的三个代码写法上的区别是:1.赋值方式有无单引号 ’ ,2.数组定义方式bit[2:0] [7:0]arr,bit arr[2:0][7:0](注意数组高低维度),3.只有bit和logic可以用于合并形

module tb;
	struct packed{
		logic[7:0] r;
		logic[7:0] g;
		logic[7:0] b;
		} pixel_a, pixel_b, pixel_c;

	initial begin
		pixel_a = {8'h12, 8'h24, 8'h36};
		print_pixel({pixel_a.r, pixel_a.g, pixel_a.b})
		pixel_b = pixel_a;
		print_pixel({pixel_b.r, pixel_b.g, pixel_b.b})
		pixel_b = {g:8'haa, b:8'hbb, r:8'hcc};
		print_pixel({pixel_b.r, pixel_b.g, pixel_b.b})//通过索引赋值,数组里也有这个用法
	end
	
	function void print_pixel(logic[2:0][7:0] pix_arr);
		$display("r = %0x, g = %0x, b = %0x", pix_arr[2], pix_arr[1], pix_arr[0]);//%x是十六进制
	endfunction

endmodule

这段代码中,我们对结构体struct添加了packed,添加了packed后,会将结构体里的r,g,b紧密的存放在一起,节省空间。也就意味着r,g,b缩减为一个向量。

struct packed{
logic[7:0] r;
logic[7:0] g;
logic[7:0] b;
} pixel_a, pixel_b, pixel_c;

此时,结构体变成了一个合并形数组,对合并形数组的赋值,我们的赋值方式是{ },没有单引号 '。

initial begin
pixel_a = {8’h12, 8’h24, 8’h36};
print_pixel({pixel_a.r, pixel_a.g, pixel_a.b})
pixel_b = pixel_a;
print_pixel({pixel_b.r, pixel_b.g, pixel_b.b})
pixel_b = {g:8’haa, b:8’hbb, r:8’hcc};
print_pixel({pixel_b.r, pixel_b.g, pixel_b.b})
end

函数形式参数里引入的数组类型的定义方式也要发生变化,更改为合并形数组类型

function void print_pixel(logic[2:0][7:0] pix_arr);

4.利用typedef将struct定义为一个类型

module tb;
	typedef struct packed{
		logic[7:0] r;
		logic[7:0] g;
		logic[7:0] b;
		} pixel_t 
		pixel_t pixel_a, pixel_b, pixel_c;

	initial begin
		pixel_a = {8'h12, 8'h24, 8'h36};
		print_pixel(pixel_a)
		pixel_b = pixel_a;
		print_pixel(pixel_b)
		pixel_b = {g:8'haa, b:8'hbb, r:8'hcc};
		print_pixel(pixel_b)//通过索引赋值,数组里也有这个用法
	end
	
	function void print_pixel(pixel_t pix);
		$display("r = %0x, g = %0x, b = %0x", pix.r, pix.g, pix.b);//%x是十六进制
	endfunction

endmodule

利用typedef将struct定义为一个类型pixel_t后,在函数里就可以引入该类型的形式参数了

function void print_pixel(pixel_t pix);

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值