SV第二章 数据类型

2.3 动态数组

SV中提供了动态数组类型,可以在仿真时分配空间或调整宽度,这样在仿真中可以使用最小的存储量。
动态数组在声明时使用空的下标[]。数组的宽度不在编译时给出,而在程序运行时再指定。使用new[]操作符来分配空间。

int dyn[],d2[];`	// 声明动态数组
initial begin
	dyn[] =new[5];	// 分配5个元素
	foreach (dyn[j]) 
		dyn[j] = j;	// 对元素进行初始化
	d2 =dyn;	// 复制一个动态数组
	d2[0] =5 ;	// 修改复制值
	$display(dyn[0],d2[0]);	// 显示数值(0和5)
	dyn = new[20](dyn) ;	 // 分配20个整数值进行并复制原有5个元素
	dyn = new[100];		// 分配100个新的整数值
	dyn.delete();		// 删除所有元素
end

// 使用动态数组来保存元素数量不定的列表
bit[7:0] mask[] =`{ 8'b0000_0000,8'b0000_00001,
				   8'b0000_0011,8'b0000_0111,
				   8'b0000_1111,8'b0001_1111,
				   8'b0011_1111,8'b0111_1111,
				   8'b1111_1111
				};

只要基本数据类型相同,例如都是int,怎定宽数组和动态数组之间可以相互赋值

2.4 队列

SV中引进新的数据类型–队列,结合了链表和数组的优点。
队列与链表相似,可以在队列中任何地方增加或删除元素。
队列与数组相似,可以通过索引实现对任一元素的访问,不需像链表一样遍历。
队列的声明是使用带有美元符号的下标:[$]。

2.4.1 队列的方法操作

int  j=1, q2[$]={3,4}, q[$]={0,2,5};

initial begin
	q.insert(1,j);	//{0,1,2,5}	在2之前插入i
	q.insert(3,q2);	// {0,1,2,3,4,5} 在q中插入一个队列
	q.delete(1); 		// {0,2,3,4,5} 删除第1个元素

// 下面的操作执行速度很快
q.pus_front(6);	// {6,0,2,3,4,5}在队列掐面插入
j=q.pop_back();	//{6,0,2,3,4}  j=5;
q.push_back(8);	//{6,0,2,3,4,8} 在队列末尾插入
j=q.pop_front() 	//{0,2,3,4,8} j=6

foreach(q[i])
	$display(q[i]);	// 打印整个队列

q.delete();	// {} 删除整个队列
end

使用字下标串联来替代方法。[ : 2 ] 代 表 [ 0 : 2 ] ; [ 1 : :2]代表[0:2];[1: :2][0:2][1:]代表[1:2]; $在左边代表最小值,在右边代表最大值。
队列中元素是连续存放的,队列头尾增删方便,在中间增删需要搬移

int  j=1, q2[$]={3,4}, q[$]={0,2,5};

initial begin
	q = {q[0], j , q[1:$]};	//在0和1之间插入
	q = {q[0:2],q2,q[3:$]};	//插入队列
	q = {q[0],q[2:$]};
	
// 下面执行速度很快
q = {6,q}; //队列前面插入
j = q[$]; 	// 下标最大值
q = {q,8}
j=q[0];
q= q[1:$]; 	// 从队列前面取出数据
q = {};	// 删除整个队列
end

2.5 关联数组

SV中提供关联数组类型,用来保存稀疏矩阵的元素。对一个非常大的地址空间进行寻址时,SV只为实际写入的元素分配空间。
仿真器采用树或哈希表的形式来存放关联数组。

2.6 链表

虽然SV提供了链表,但是应避免使用,因为有队列。

2.7 数组的方法

SV提供很多数组的方法,用于非合并的数组类型,例如定宽数组,动态数组,队列和关联数组。

2.7.1 数组缩减方法

基本的数组缩减方法是把一个数组缩减成一个值。
最常用缩减方法是sum,常常搭配with使用。
其他数组缩减方法:product积,and与,xor异或。

// 数组求和
bit on[10];	
int total;//

initial begin
	foreach(on[i])
		om[i] = i;
// 打印出单比特和
$display("on.sum = %0d",on.sum);

// 打印出32比特和
$display("on.sum = %0d",on.sum+32'd0);

// 由于total是32比特值,所有数组和也是32比特值
total = on.sum;
$display("total = %0d",total);

// 将数组和与一个32比特数进行比较
if(on.sum >= 32'd5)
	$display("sum has 5 or more 1's");

//使用带32比特有符号运算的wit表达式
$display("int sum = %0d",on.sum with(int'(item)));
end 

// 从一个关联数值中随机选取一个元素
int aa[int],rand_index,element,count;
element = $urandom _range(aa.size()-1);

foreach(aa[i])
	if(count++ ==element) begin
		rand_idx = i;	// 保存关联数组的索引
		break;
end
	
$display(" %0d element aa[%0d] = %0d",element,rand_idx,aa[rand_idx]);

2.7.2 数组定位方法

方法返回的是队列而非标量。

int f[6] = '{1,6,2,6,8,6};
int d[] ='{2,4,6,8,10};
int q[$] = {1,3,5,7},tq[$];

tq =q.min();
tq = d.max();
tq = f.unique();	//返回在数组中具有唯一值的队列。
  • 数组定位方法:find
int d[] = '{9,1,8,3,4,4}, tq[$];
// 找出所有大于3的元素
tq = d.find with (item>3);
// 等效如下
tq.delete();	// 清空
foreach(d[i])
	if(d[i] >3)
		tq.push_back(d[i])

// item 为重复参数
tq = d.find_index with(item>3);
tq= d.find_first with(item>9);
tq= d.find_last with(item==4);
tq = d.find_first_index with(item==8);
tq =d.find_last_index with(item==4);

2.7.3 数组排序

数组排序不同于数组定位方法,是改变了原始数组,数组定位方法是新建了一个队列来保存结果。

// 对数组排序
int d[] = `{9,1,8,3,4,4};
d.revese();
d.sort();
d.rsort();
d.shuffle();

// 如何使用子域对一个结构进行排序
struct packed{byte red, green,blue;}  c[];
initial begin
	c = new[100];	// 分配100个像素
	foreach(c[i])
		c[i] = $urandom;	// 填上随机数

	c.sort with(item.red);		// 只对红色(red)像素进行排序
	
	// 先对绿色green像素后对蓝色blue像素进行排序
	c.sort(x) with ({x.green,x.blue});

end

2.7.4 使用数组定位方法建立积分板

数组定位方法可以用来建立计分板。
示例:定义了包结构Packet,然后建立一个由包结构队列组成的计分板。

typedef struct packed{
					bit[7:0] addr;
					bit[7:0] pr;
					bit[15:0] data;
				}  Packet;

Packet scb[$];

// check_addr()函数在记分板里寻找和参数匹配的地址
function void check_addr(bit[7:0] addr);
	int intq[$];
	
	intq = scb.find_index() with (item.addr ==addr);
	case(intq.size())
	0: $display("Addr %h not found in scoreboard",addr);
	1:scb.delete(intq[0]);
	default:
		$display("ERROR:Multiple hits for addr %h",addr);
	endcase

endfunction:check_addr
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值