【IC验证】systemverilog_数组

一.概述

1.数组的分类

systemverilog中,除了有定长数组外,还扩展了动态数组、队列和关联数组;
在这里插入图片描述

2.数组的基本规则

(1)在声明变量时,变量名右侧的维度大于变量名左侧的维度,变量名同一侧的维度从左向右递减;
在这里插入图片描述
(2)变量的索引,索引位于变量名右侧,且维度从左导游递减;
在这里插入图片描述
(3)systemverilog中,数组的每个元素存储时使用的是32bite字边界,当单个元素超过32位时,就增加到多个32bite字边界;
(4)在sysytemverilog中,存储一bit4值逻辑需要消耗2bit存储空间(四个状态0,1,X,Z);
(5)byte,shortint,int,longint只能声明非组合型数组(存疑)???,bit、logic既可以声明组合型数组和非组合型数组;

二.定长数组

1.定义

在声明时必须明确指定大小(上下界或宽度)的数组。

2.非组合型数组

(1)定义

数组,各元素,独立分配存储空间;

(2)语法

在变量声明时,维度声明在变量名侧;
声明语法

变量类型 变量名 维度;

初始化及赋值语法
多个元素或整体初始化或赋值时,每一维一个**‘{}**
非组合型数组初始化或赋值时,赋的值和被赋值的元素结构必须一致;

被赋值元素 = 赋的值;

(3)例子

A 例子1:非组合型数组结构及存储空间分配
代码:

module test_array;
    bit [7:0] a [0:2] = '{1,2,3}; 
    initial begin
        $display("a = %b",a[0]);
    end
endmodule

说明:
声明了3个元素,每个元素(a[0]、a[1]、a[2]各)都会分配32位宽的存储空间,但是只使用了低8位;
在这里插入图片描述
B 例子2:非组合型数组的声明初始化及赋值
代码:

module test_array;
    int b [3:0][2:0];
    int c [1:0][2:0];
    initial begin
        b = '{'{0,1,2},'{3,4,5},'{6,7,8},'{9,10,11}};
        c = '{'{12,13,14},'{15,16,17}};
	    $display("b[1][2] = %0d",b[1][2]);
        b[1][2] = 18;
        $display("b[1][2] = %0d",b[1][2]);
	    b[0] = c[0];
	    $display("b[0][2] = %0d",b[0][2]);
        b[0]= '{19,20,21};
        $display("b[0][2] = %0d",b[0][2]);
    end
endmodule

结果:
在这里插入图片描述

(4)特殊点

A非组合型数组,每一个维度指定,可以按照[msb:lsb]的方式,也可以按照[size]的方式;
B非组合型数组的初始化或赋值,可以用’{default:值}的方式,表示将每一个元素都赋值为指定的值;

3.组合型数组

(1)定义

数组,各元素,组合分配地连续的存储空间;

(2)语法

在变量声明时,维度声明在变量侧;
声明语法

变量类型  维度 变量名;

初始化及赋值语法
很灵活,支持拼接赋值,位宽不一致(同verilog,短了高位补0,长了截断);

被赋值元素 = 赋的值;

(3)例子

A非组合型数组的声明和初始化
代码

module test_array;
    bit [3:0][7:0] d;
    initial begin
        d = 32'h8888_8888;
        $display("d = %h",d);
        d = {8'h12,8'h34,8'h56,8'h78};
        $display("d = %h",d);
    end
endmodule

结果:
在这里插入图片描述
说明:
声明了4个8位宽的组合型数组,存储空间分配的存储空间的梁旭的4*8=32位:
在这里插入图片描述

(4)特殊点

A组合型数组连续存放的优点有:节省存储空间,方便存读;

4.混合型数组

(1)定义

数组,既包含组合型数组的部分,又包含非组合型数组的部分;

(2)语法

声明语法

变量类型  维度 变量名 维度;

初始化及赋值语法
组合型部分按照组合型部分赋值,非组合型部分按照非组合型赋值;

(3)特殊点

组合型数组组合部分不可以赋值给非组合型数组,非组合型数组不可以赋值给组合型数组的组合部分;

5.foreach循环

(1)简介

在**()**中给出变量名和索引,sysytemverilog会自动遍历数组中的元素;

(2)语法

foreach(元素名[索引])begin
	具体操作;
end

(3)例子

代码:

module test_array;
    int a [10];
    initial begin
        foreach(a[i])begin
            a[i] = i;
            $display("a[%0d] = %0d",i,a[i]);
        end
    end
endmodule

结果:
在这里插入图片描述

(4)注意点

索引是可以引用,但不可以更改;

6.数组相关的系统函数

(1)dimensions

A作用:返回数组的维度;
B语法:

dimensions(数组名)

C例子

module test_array;
    int a [0:3][0:1];
    bit [3:0] b [0:1];
    initial begin
        $display("The dimensions of a is %0d",$dimensions(a));
        $display("The dimensions of b is %0d",$dimensions(b));
    end
endmodule

结果:
在这里插入图片描述

(2)$size

A作用:返回指定维度的尺寸大小
B语法

$size(数字名,维度)

C例子
代码:

    int a[0:3][0:2];
    bit [3:0] b [0:2];
    initial begin
        $display("a's first dimension is %0d",$size(a,1));
        $display("a's thied dimension is %0d",$size(a,3));
        $display("b's second dimension is %0d",$size(b,2));
    end
endmodule

结果:
在这里插入图片描述

三.动态数组

1.定义

在声明时不需要明指定大小,且可以随时改变大小的数组;

2.语法

(1)声明语法:

类型 数组名 [];

(2)初始化大小或改变数组大小的语法:
方法1:通过new函数

变量名 = new[大小]

方法二:通过变量赋值

变量名 = 赋值变量;

方法三:常量赋值:同非组合型数组

变量名 ='{1,值2,...}

(3)开辟新的存储空间并保留原值

变量名 = new[大小](变量名);

(4)清空动态数组
方法一:

数组名.delete();

方法二:

数组名=new[0];

3.例子

代码:

module test_array;
    int a[],b[],c[];
    initial begin
        $display("%0d,%0d",$size(b,2),$size(b,1));
        a = new[4];
        b = new[3];
        c = new[2];
        $display("a's size is %0d",$size(a,1));
        $display("b's size is %0d",$size(b,1));
        b = a;
        $display("b's size is %0d",$size(b,1));
        c = '{1,2};
        //
        foreach(b[i])begin
            b[i] = i;
            $display("b[%0d] = %0d",i,b[i]);
        end
        b = new[5](b);
        foreach(b[i])begin
            $display("b[%0d] = %0d",i,b[i]);
        end
        //
        b.delete();
        $display("b's dimension is %0d",$dimensions(b));
        $display("%0d,%0d",$size(b,2),$size(b,1));
    end
endmodule 

结果:
在这里插入图片描述

四.队列

1.定义

队列是数组和链表的结合,我们可以在任意位置添加或删除数据成员;

2.语法

(1)队列的声明

类型 队列名 [$];

(2)队列的初始化和赋值
方法一:通过赋常量(注意{}旁没有')

队列名 = {1,值2...}; //注意{}没有'

方法二:通过赋队列(队列2会将值和队列大小同时赋给队列1)

队列1= 队列2; //注意{}没有'

方法三:可以通过拼接赋值

队列1= {队列2名,值,队列3}

(3)常用的系统函数
A insert
说明:在指定位置插入值
语法:队列.insert(位置,值);
注意:队列不能插入队列
B delete
说明:删除指定位置的值,或删除所有元素
语法:队列名.delete(索引);//删除指定位置的值,仅适用于队列,不适用于动态数组
队列名.selete();
C push和pop
队列名.push_front(值):在队列前面插入一个值;
存储变量=队列名.pop_front:在队列前面取出一个值;
队列名.push_back(值):在队列后面插入一个值;
存储变量=队列名.pop_back:在队列后面取出一个值;

3.例子

代码:

module test_array;
    int a [$];
    int b [$];
    int c [$];
    initial begin
        a = {1,2,3};
        b = {5,6};
	  c = {10,b[0:1]};
        $display("a is %p",a);
        $display("b is %p",b);
        $display("c is %p",c);
        b = a;
        $display("b is %p",b);
        b.insert(1,7);
	  b.delete(2);
        $display("b is %p",b);
        void'(a.pop_front);
	  a.push_front(8);
	  void'(b.pop_back);
        b.push_back(9);
        $display("a is %p",a);
        $display("b is %p",b);
    end
endmodule

结果:
在这里插入图片描述

4.注意点

(1)队列的索引$表示最后一个元素;

五.关联数组

1.定义

索引可以是任意类型(logic,bit,byte,short,int,long,字符串,枚举类型),存储可以不连续的一种数组;

2.语法

(1)声明语法

数据类型 大小 名字 [索引类型及大小]

(2)初始化、赋值、改变大小

A 赋常量(键为索引,值为取值)
关联数组名 = '{键1:值1,键2:值,…}
B 赋关联数组
关联数组1名 = 关联数组2名;

(3)关联数组相关的函数

A delete
作用:删除关联数组中的键值对;
语法:关联数组名.delete(索引);

(4)例子

代码:

    int a [string];
    int b [string]; 
    initial begin
        a = '{"name":1,"age":12,"weigh":45};
        $display("a is %p",a);
	  b = '{"hong":1,"lan":2};
	  $display("b is %p",b);
	  b = a;
	  $display("a is %p",b);
	  b.delete("age");
	  $display("a is %p",b);
    end
endmodule

结果:
在这里插入图片描述

六.数组常用方法

1.缩减方法

(1)sum
作用:元素求和
语法:和值存储变量 = 数组.sum();
(2)product
作用:元素求积
语法:积值存储变量 = 数组.product();
(3)and
作用:元素按位与
语法:结果存储变量 = 数组.and();
(4)or
作用:元素按位或
语法:结果存储变量 = 数组.or();
(5)xor
作用:元素按位异或
语法:结果存储变量 = 数组.xor();
(6)例子
代码:

module test_array14;
	int a[0:3];	
	initial begin
		a = '{1,2,3,4};
		$display("sum is %0d",a.sum());
		$display("product is %0d",a.product());
             $display("and is %0b",a.and());  
 		$display("or is %0b",a.or());
		$display("xor is %0b",a.xor());
	end 
endmodule

结果:
在这里插入图片描述

2.定位方法

(0)注意
定位函数的返回值是一个队列,而不是一个元素,所以打印要用%p;
(1)min
作用:元素最小值
语法:结果存储变量 = 数组.min();
(2) max
作用:元素最小值
语法:结果存储变量 = 数组.max();
(3)unique
作用:遍历不同的值
语法:结果存储变量 = 数组.unique();
(4)例子
代码:

endmodule
module test_array15;
	int b[];
	initial begin
		b = '{1,2,3,3,5,5,7,9};
		$display("max is %p",b.max());
		$display("min is %p",b.min());
		$display("unique is %p",b.unique());
	end
endmodule 

结果:
在这里插入图片描述

3.排序方法

(1)reverse
作用:倒序
语法:结果存储数组 = 数组.reverse();
(2)sort
作用:增序排列
语法:结果存储数组 = 数组.sort();
(3)rsort
作用:降序排列
语法:结果存储数组 = 数组.rsort();
(4)例子
代码:

module test_array16;
	int a [0:5] = '{1,3,5,7,8,9};
	int b []    = '{2,3,5,6,7,9};
	int c [$]   = {1,3,4,5,7,8};
	initial begin
		a.reverse();
		$display("reverse is %p",a);
           	b.sort();
		$display("sort is %p",b);
		c.rsort();
		$display("rsort is %p",c);
	end
endmodule 

结果:
在这里插入图片描述

4.size

四种数组中,哪个数组可以使用size内嵌方法?
动态数组、队列、关联数组都可以,定长数组不可以;
要注意函数$size和内嵌方法size的区别
所有数组$size函数,但是后续三个数组可以用用size内嵌方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值