SystemVerilog数据类型和操作方法

1. 内建数据类型

1.1 逻辑(logic)类型

逻辑类型相当于verilog中reg变量的改进版,是的变量可以被连续赋值、门单元和模块所驱动;任何使用线网的地方都可以使用logic,唯一要注意的是logic不能进行多驱。

logic q,q_l,d,clk,rst_l;

1.2  双状态数据类型

双状态数据类型只有0,1两种取值,没有x和z态,这种类型有助于减少仿真时的内存占用。

bit b;                     //双状态,单比特
bit [31:0] b32;            //双状态,32比特无符号整数
int unsigned ui;           //双状态,32比特无符号整数

int i;                     //双状态,32比特有符号整数
byte b8;                   //双状态,8比特有符号整数
shortint s;                //双状态,16比特有符号整数
longint l;                 //双状态,64比特有符号整数

interger i4;               //四状态,32比特有符号整数
time t;                   //四状态,64比特无符号整数

2.定宽数组

2.1 定款数组的声明和初始化

SV中的定宽数组支持便捷声明方式,可以省略下边界,此时下边界默认为0。

//一维数组
int lo_hi[0:15];             //16个整数[0]...[15]
int c_style[15];             //16个整数[0]...[15]

//二维数组
int array2[0:7][0:3]         //完整的声明,一个8行4列的数组
int array2[8][4];            //紧凑的声明
array2[7][3]=1;              //设置最后一个元素

2.2 常量数组 

在定义数组的同时,可以用一个单引号加大括号来初始化数组。

int ascend[4] = '{0,1,2,3};            //对四个元素进行初始化
int descend[5];

descend = '{4,3,2,1,0};                //为五个元素赋值
descend[0:2] = '{5,6,7};               //为部分元素赋值
descend = '{9,8,default:1};            //{9,8,1,1,1}

2.3 基本的数组操作 

数组中最常用的是for和foreach循环。

//一维数组
initial begin
  bit[31:0] src[5],dst[5];
  for(int i=0;i<$size(src);i++)
    src[i]=i;
  
  foreach(dst[j])
    dst[j]=src[j]*2;  //dst的值是src的两倍
end


//多维数组
int md[2][3];         //一个3行4列的数组

initial begin

  md = '{'{9,8,7},'{3{32'd5}}};

  foreach(md[i][j])
    $display("md[%0d][%0d]=%0d",i,j,md[i][j]);
end

数组可以在不使用循环的情况下进行比较和复制,注意此时操作的对象是整个数组;

initial begin
  bit[31:0] src[5]='{0,1,2,3,4},
            dst[5]='{5,4,3,2,1};

  if(src==dst)
    $display("src==dst");
  else
    $display("src!=dst");
end

2.4 合并数组

不同于非合并数组,合并数组的存放方式是连续的比特集合,中间没有任何闲置的空间。比如非合并数组的4个byte只会占用完整的1个字的内存,而非4个字进行高位补0。

声明合并数组时,合并的位和数组大小作为数据类型的一部分必须在变量名前面指定。 数组大小定义的格式必须是[msb:lsb],而不是[size]。

bit [3:0][7:0] bytes;          //4个字节组装成32比特
bytes = 32'hCafe_Dada;

$displayh(bytes,,              //显示所有的32比特
          bytes[3],,           //最高字节“CA”
          bytes[3][7]);        //最高比特位“1”

3.动态数组

SystemVerilog 提供了动态数组类型,可以在仿真时分配空间或调整宽度,这样就在仿真中就可以使用最小的存储量。

数组最开始是空的,所以必须调用new[]操作符来分配空间,同时在方括号中传递数组宽度。

int dyn[],d2[];                  //声明动态数组

initial begin
  dyn=new[5];                    //分配5个元素
  foreach(dyn[j]) dyn[j]=j;      //对元素进行初始化
  d2=dyn;                        //复制一个动态数组
  d2=5;                          //修改复制值
  dyn=new[20](dyn);              //分配20个整数值并进行复制
  dyn=new[100];                  //分配100个新的整数值,旧值不复存在
  dyn.delete();                  //删除所有元素
end

4.队列 

队列可以在任何地方增加或者删除元素,且性能损失比动态数组小的多。动态数组需要分配新的数组并复制所有元素的值。而且队列可以通过索引去实现任意元素的访问,不需要像链表一样去遍历目标元素之前的所有元素。

队列的声明是使用带美元符号的下标:[$]。队列元素编号从0到$。

int j=1,
    q2[$]={3,4},               //对列的常量不需要'
    q[$]={0,2,5};              //{0,2,5}

initial begin

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

  //下面操作执行很快
  q.push_front(6);             //{6,0,2,3,4,5} 在队列前面插入6
  j=q.pop_back;                //{6,0,2,3,4}   j=5
  q.push_back(8);              //{6,0,2,3,4,8} 在队列末尾插入8
  j=q.pop_front;               //{0,2,3,4,8}   j=6
  q.delete();                  //{}            删除整个队列

end

5.关联数组 

用于超大规模范围的数组,用来保存稀疏矩阵的元素,只为实际写入的元素分配空间。仿真器采用树或者哈希表的形式来存放关联数组。

关联数组采用在方括号中放置数据类型的形式来进行声明。

initial begin
bit [63:0] assoc[bit[63:0]],idx=1;

//对稀疏分布的元素进行初始化
repeat(64) begin
  assoc[idx] = idx;
  idx = idx <<1;
end

//使用foreach遍历数组
foreach (asssoc[i])
  $display("assoc[%h]=%h",i,assoc[i]);
  
//使用函数遍历数组
if(assoc.first(idx))
  begin                     //得到第一个索引                  
    do
      $display("assoc[%h]",idx,assoc[idx]);
    while(assoc.next(idx)); //得到下一个索引
  end

//找到并删除一个元素
assoc.first(idx);
assoc.delete(idx);
$display("The array now has %0d elements",assoc.num);

end

6.链表

SystemVerilog虽然提供了链表,但应该避免使用它,队列的数据类型更加高效易用。

7.数组的方法

7.1 数组缩减方法

基本的数组缩减方法是把数组缩减成一个值。常见的数组缩减方法有sum(和),product(积),or(或)和xor(异或)。

bit on[10];                          //单比特数组
int total;

initial begin
  foreach(on[i])
    on[i]=i;                         //on[i]的值为0或1

//打印单比特和  
$display("on.sum=%0d",on.sum);       //on.sum=1

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

//由于total是32比特变量,所以数组和也是32比特
total=on.sum;                        //total=5

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

7.2 数字定位方法

数组定位方法:min,max,unique,find。这些函数的返回值是一个队列而非标量。

在条件语句with中,item被称为重复参数,它代表数组中一个单独的元素。 

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;         //{1}
tq = d.max;         //{10}
tq = f.unique;      //{1,6,2,8}

tq = d.find with(item > 2);            //{4,6,8,10}
tq = d.find_index with(item>3)         //{1,2,3,4}
tq = d.find_first with(item>99)        //{}
tq = d.find_first_index(item==4)       //{1}
tq = d.find_last with(item==10)        //{10}
tq = d.find_last_index with(item==10)  //{4}

7.3 数组的排序

数组排序方法:reverse(翻转)、sort(递增)、rsort(递减)和shuffle(乱序)。

int d[] = '{9,1,8,3,4,4};
d.reverse();               //{4,4,3,8,1,9}
d.sort();                  //{1,3,4,4,8,9}
d.rsort();                 //{9,8,4,4,3,1}
d.shuffle();               //{9,4,3,8,1,4}

8.strcut类型

SystemVerilog支持struct结构体,用于把数据组织到一起,创建新类型。

typedef struct {bit[7:0] r,g,b;} pixel_s;
pixel_s my_pixel;

9.枚举类型、

枚举类型可以自动为列表中的每个名称分配不同的数值。枚举值缺省为从0开始的整数。

typedef enum{INIT,DECODE,IDLE} fsmstate_e;
fsmstate_e pstate,nstate;

initial begin
  case(pstate)
    IDLE:nstate=INIT;
    INIT:nstate=DECODE;
    default:nstate=IDLE;
  endcase
  $display("Next state is %s",nstate.name());  //显示状态的符号名
end

10.常量

SystemVerilog支持const修饰符,允许变量声明时对其进行初始化,但不能在过程代码中修改其值。

initial begin
  const byte colon=":";
  ...
end

11.字符串

SystemVerilog中的string变量可以用来保存长度可变的字符串。单个字符是byte类型。

string s;

initial begin
  s="IEEE ";
  $display(s.getc(0));         //显示:73('I')
  $display(s.tolower());       //显示:ieee
  
  s.putc(s.len()-1,"-");       //将空格变为'-'
  s={s,"P1800"};               //"IEEE-P1800"
  
  $display(s.substr(2,5));     //显示:EE-P
end

  • 26
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SystemVerilog ,数组是一种非常有用的数据类型,可以存储和处理大量数据。以下是一些常用的 SystemVerilog 数组方法: 1. count():返回数组与指定值相等的元素个数。 ``` int my_array[5] = {1, 2, 3, 2, 4}; $display("Number of 2's in the array: %d", my_array.count(2)); ``` 2. find():查找数组第一个与指定值相等的元素的索引。如果未找到,则返回-1。 ``` int my_array[5] = {1, 2, 3, 2, 4}; $display("Index of the first occurrence of 2: %d", my_array.find(2)); ``` 3. find_first_index()和find_last_index():查找数组第一个和最后一个与指定值相等的元素的索引,如果未找到,则返回-1。 ``` int my_array[5] = {1, 2, 3, 2, 4}; $display("Index of the first occurrence of 2: %d", my_array.find_first_index(2)); $display("Index of the last occurrence of 2: %d", my_array.find_last_index(2)); ``` 4. unique():返回一个新数组,其包含原始数组的所有唯一元素。如果原始数组有重复元素,则只包含第一次出现的元素。 ``` int my_array[5] = {1, 2, 3, 2, 4}; int unique_array[$]; unique_array = my_array.unique(); $display("Unique elements in the array: %p", unique_array); ``` 5. sort():按升序对数组进行排序。 ``` int my_array[5] = {3, 1, 4, 2, 5}; my_array.sort(); $display("Sorted array: %p", my_array); ``` 6. reverse():将数组的元素反转。 ``` int my_array[5] = {1, 2, 3, 4, 5}; my_array.reverse(); $display("Reversed array: %p", my_array); ``` 这些方法只是 SystemVerilog 数组的一部分,还有其他方法可用于数组的创建、初始化、操作和遍历。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值