SystemVerilog教程之Data Types Part2

· User defined types ·

用户定义类型与其他编程语言中的类型相同,用户可以使用typedef定义自己的数据类型。

`timescale 1ns/10ps
// Type define a struct
typedef struct {
byte a;
reg b;
shortint unsigned c;
} myStruct;

module typedef_data ();
// Full typedef here
typedef integer myinteger;
// Typedef declaration without type
typedef myinteger;
// Typedef used here
myinteger a = 10;
myStruct object = '{10,0,100};
initial begin
$display ("a = %d", a);
$display ("Displaying object");
$display ("a = %b b = %b c = %h", object.a, object.b, object.c);
#1 $finish;
end
endmodule

输出

a = 10
Displaying object
a = 00001010 b = 0 c = 0064
 · Class Types  ·  

Class是一组数据和对该数据进行操作的方法( methods)。类中的数据称为属性( properties)。类中的属性和方法一起定义了类对象( object)的内容和功能。

我们可以动态地对类进行创建和销毁,然后通过句柄传递。

module class_data();
// Class with local fields
class Packet;
int address;
bit [63:0] data;
shortint crc;
endclass:Packet
// Class with task
class print;
task print_io (input string msg);
$display("%s",msg);
endtask:print_io
endclass:print
// Create instance
Packet p;
print prn;
initial begin
// Allocate memory
p = new();
prn = new();
// Assign values
p.address = 32'hDEAD_BEAF;
p.data = {4{16'h55AA}};
p.crc = 0;
// Print all the assigned values
$display("p.address = %d p.data = %h p.crc = %d",
p.address, p.data, p.crc);
prn.print_io("Test calling task inside class");
$finish;
end
endmodule
输出


p.address = -559038801 p.data = 55aa55aa55aa55aa p.crc = 0
Test calling task inside class

· Casting ·

与C语言中一样,Casting(类型转换)用于将一种类型的数据转换为另一种类型的数据。可以使用强制转换(’)操作更改数据类型。

module casting_data();
int a = 0;
shortint b = 0;
initial begin
$monitor ("%g a = %d b = %h", $time, a , b);
#1 a = int'(2.3 * 3.3);
#1 b = shortint'{8'hDE,8'hAD,8'hBE,8'hEF};
#1 $finish;
end
endmodule

输出

a = 0 b = 0000
a = 8 b = 0000
a = 8 b = beef

· Arrays ·

数组是相同的类型变量的集合,可以使用索引进行访问。

在C语言中,数组从0开始索引。尽管C语言可以初始化整个数组,但在程序中使用时只能单独读写每个元素。

在Verilog-2001中,reg和wire数据类型都可以声明为数组,并且需要在对象名称之前声明数组宽度,还可以在对象名称之后声明的数组的维度。

Packed and Unpacked arrays

SystemVerilog使用术语 packed array来表示维度在对象名称之前的数组,使用术语 unpacked array来表示维度在对象名称之后的数组。

Packed arrays只能由单bit类型( bit, logic, reg, wire)和其他packed arrays组成。

Example - Packed Unpacked array

module packed_unpacked_data();
// packed array
bit [7:0] packed_array = 8'hAA;
// unpacked array
reg unpacked_array [7:0] = '{0,0,0,0,0,0,0,1};
initial begin
$display ("packed array[0] = %b", packed_array[0]);
$display ("unpacked array[0] = %b", unpacked_array[0]);
$display ("packed array = %b", packed_array);
// Below one is wrong syntax
//$display("unpacked array[0] = %b",unpacked_array);
#1 $finish;
end
endmodule

Simulation Output

packed array[0] = 0
unpacked array[0] = 1
packed array = 10101010

· Dynamic arrays ·

动态数组是unpacked array,其大小可以在运行时设置或更改。

动态数组的内存空间直到运行时显式创建才分配。

SystemVerilog还提供了一组用于处理动态数组的函数。

new []:用于新建数组,设置大小。
size():返回数组的当前大小。
delete():清除所有数组元素。

Example - Dynamic Array

module dynamic_array_data();
// Declare dynamic array
reg [7:0] mem [];
initial begin
// Allocate array for 4 locations
$display ("Setting array size to 4");
mem = new[4];
$display("Initial the array with default values");
for (int i = 0; i < 4; i ++) begin
mem[i] = i;
end
// Doubling the size of array, with old content still valid
mem = new[8] (mem);
// Print current size
$display ("Current array size is %d",mem.size());
for (int i = 0; i < 4; i ++) begin
$display ("Value at location %g is %d ", i, mem[i]);
end
// Delete array
$display ("Deleting the array");
mem.delete();
$display ("Current array size is %d",mem.size());
#1 $finish;
end
endmodule

Simulation Output

Setting array size to 4
Initial the array with default values
Current array size is 8
Value at location 0 is 0
Value at location 1 is 1
Value at location 2 is 2
Value at location 3 is 3
Deleting the array
Current array size is 0

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 queue
queue.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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值