story · 2020年05月13日

SystemVerilog教程之Data Types Part-4

Associative arrays

动态数组适合处理动态变化的变量集合,但当集合的数据空间稀疏时,**关联数组( associative array)**是更好的选择。

关联数组在使用之前不会分配任何内存,并且索引不限于整数,可以是任何类型。

举一个 memory controller验证的例子,通常会进行随机写入/读取 testcases 的验证。具有固定大小的memory会花费大量的系统资源。因此,我们可以使用关联数组,仅验证需要使用的地址。

其声明语法为:

    data_type array_id [ index_type ];

data\_type是数组元素的数据类型。
array\_id是要声明的数组的名称。
index\_type是要用作索引的数据类型。

Queues

队列是大小可变的有序元素的集合。队列中的每个元素都由一个序号表示,该序号表示其在队列中的位置,0表示第一个,$表示最后一个。

队列类似于自动增长和收缩的一维 unpacked array。因此,与数组一样,可以对数组进行使用索引连接切片比较运算。

Queue Operators

索引0:用于访问队列的第一个元素
索引$:用于访问队列的最后一个元素

Queues methods

SystemVerilog提供以下方法来处理队列

insert()方法在指定的索引位置插入指定的元素。
delete()方法删除指定索引位置的元素。
pop_front()方法删除并返回队列的第一个元素。
pop_back()方法删除并返回队列的最后一个元素。
push_front()方法将给定元素插入队列的前面。
push_back()方法将给定元素插入队列的末尾。
size()方法返回队列中的元素数。如果队列为空,则返回0。

Example - Queues

module queue_data();
// Queue is declated with $ in array size
integer queue[$] = { 0, 1, 2, 3, 4 };
integer i;
initial begin
$display ("Initial value of queue");
print_queue;
// Insert new element at begin of queue
queue = {5, queue};
$display ("new element added using concate");
print_queue;
// Insert using method at begining
queue.push_front(6);
$display ("new element added using push_front");
print_queue;
// Insert using method at end
queue.push_back(7);
$display ("new element added using push_back");
print_queue;
// Using insert to insert, here 4 is index
// and 8 is value
queue.insert(4,8);
$display ("new element added using insert(index,value)");
print_queue;
// get first queue element method at begining
i = queue.pop_front();
$display ("element poped using pop_front");
print_queue;
// get last queue element method at end
i = queue.pop_back();
$display ("element poped using pop_end");
print_queue;
// Use delete method to delete element at index 4 in queuequeue.delete(4);
$display ("deleted element at index 4");
print_queue;
#1 $finish;
end
task print_queue;
integer i;
$write("Queue contains ");
for (i = 0; i < queue.size(); i ++) begin
$write (" %g", queue[i]);
end
$write("\n");
endtask
endmodule

Simulation Output - Queues

Initial value of queue
Queue contains 0 1 2 3 4
new element added using concate
Queue contains 5 0 1 2 3 4
new element added using push_front
Queue contains 6 5 0 1 2 3 4
new element added using push_back
Queue contains 6 5 0 1 2 3 4 7
new element added using insert(index,value)
Queue contains 6 5 0 1 8 2 3 4 7
element poped using pop_front
Queue contains 5 0 1 8 2 3 4 7
element poped using pop_end
Queue contains 5 0 1 8 2 3 4
deleted element at index 4
Queue contains 5 0 1 8 3 4

Array Methods

SystemVerilog提供以下内置方法来使用数组。此方法可以与 fixed, dynamic, queues, and associative arrays.一起使用。

sum      返回所有数组元素的总和。
product  返回所有数组元素的积。
and        返回所有数组元素的按位AND(&)。
or         返回所有数组元素的按位OR(|)。
xor     返回所有数组元素的按位XOR(^)。
min      返回所有元素中最小的数组元素。
max     返回数组元素,它是所有元素的最大值。
unique    返回具有唯一值的所有元素。

Example : Array Methods

module array_methods();
int data [0:9] = '{1,2,3,6,5,7,8,9,9,2};
int queue [$];
initial begin
queue = data.min;
$display("Min size element is %0d",queue.pop_front());
queue = data.max;
$display("Max size element is %0d",queue.pop_front());
$display("Sum of array %0d",data.sum);
$display("Product of array %0d",data.product);
$display("XOR of array %0d",data.xor);
$display("AND of array %0d",data.and);
$display("OR of array %0d",data.or);
end
endmodule

Simulation : Array Methods

Min size element is 1
Max size element is 9
Sum of array 52
Product of array 1632960
XOR of array 14
AND of array 0
OR of array 15

$cast : 动态类型转换

动态类型转换可以将一种数据类型转换成另一种数据类型。

module cast();
typedef enum {IDLE,SFD,PREAMBLE,
DATA,FCS,EFD} eth_state;
eth_state fsm;
initial begin
#5 fsm = IDLE;
$display("@%0dns Current value of FSM : %s\n",
$time,get_name(fsm));
#5 fsm = SFD;
$display("@%0dns Current value of FSM : %s\n",
$time,get_name(fsm));
#1 $cast(fsm,1+2);
$display("@%0dns Current value of FSM : %s\n",
$time,get_name(fsm));
// Below line should give compile error
//fsm = 2 + 1;
end
eth_state temp;
eth_state temp2;
integer i ;
initial begin
#20;
for(i = 0; i <= 5; i++) begin
$cast(temp,i);
$display("Value of temp is %s",
get_name(temp.next()));
end
end
function string get_name;
input lstate;
case(lstate)
IDLE : get_name = "IDLE";
SFD : get_name = "SFD";
PREAMBLE : get_name = "PREAMBLE";
DATA : get_name = "DATA";
FCS : get_name = "FCS";
EFD : get_name = "EFD";
endcase
endfunction
endmodule

Simulation Output - Cast

@5ns Current value of FSM : IDLE
@10ns Current value of FSM : SFD
@11ns Current value of FSM : DATA
Value of temp is SFD
Value of temp is PREAMBLE
Value of temp is DATA
Value of temp is FCS
Value of temp is EFD
Value of temp is IDLE

本文转载自公众号:芯片数字实验室
原文链接:
https://mp.weixin.qq.com/s/ngRoCSOS8km\_EJMcX-HuPg
未经作者同意,请勿转载!

推荐阅读

想了解更多内容,欢迎关注芯片数字实验室专栏
推荐阅读
关注数
12273
内容数
199
前瞻性的眼光,和持之以恒的学习~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息