SV 逻辑数值、数组、队列、结构体、字符串

目录

一、逻辑数值

二、变量转换

显示转换

隐式转换(不需要进行转换操作)

三、定宽数组

数组声明

多维数组声明

初始化和赋值  

非合并数组

合并数组

基本数组操作

for和foreach

赋值:=

比较:==,!=   

四、动态数组

数组定位

方法定位

with(指示sv如何搜索)

重复参数声明,意思相同

数组排序

五、队列

利用队列函数

利用队列操作

六、关联数组

七、结构体 struct

八、枚举类型enum

九、字符串

字符串声明string s


一、逻辑数值

  • 四值逻辑类型(硬件世界):logic、integer、reg、net-type(例如wire、tri)
  • 二值逻辑类型(软件世界):byte、shortint、int、longint、bit
  • 有符号类型:byte、shortint、int、longint、integer
  • 无符号类型:bit、logic、integer、reg、net-type(例如wire、tri)

注意:1.verilog中有寄存器类型reg、线网类型wire;sv侧重验证,并不关切logic对应逻 辑应该被                综合为reg还是wire。

           2.net-type(例如wire、tri)只能连续复制,logic可以连续赋值、过程块赋值。

           3.在缺省的情况下参数类型是与前一个参数相同的,而第一个参数的缺省类型是单比特输入

           4.有符号类型最高位带有符号位,例如:8位有符号数'b1000_0000,打印为-128


二、变量转换

  • 显示转换

  • 静态转换(编译阶段检查),需要在转换表达式前加上单引号,不会对转换值做检查,转换失败也无从得知。

         例如:byte signed_vec = 8’b1000_0000;

                   A=unsigned'(signed_vec);   //将signed_vec转换成无符号数

                   $display("result_vec = 'h%x",A) //’h080

  • 动态转换(仿真阶段检查),$cast(tgt,src)告诉是否成功
  • 隐式转换(不需要进行转换操作)

        例如:logic[3:0] x_vec = 'b111x;

                   Bit [2:0] b_vec;

                   b_vec = x_vec; //隐式转换,结果为’b110

注意:四值逻辑中的x、z转换成二值逻辑中的0。


三、定宽数组

  • 数组声明

                int A [0:15]; //[0]…[15] verilog中必须给上下界。

                int A [16];  //[0]…[15]。

  • 多维数组声明

                int array [0:7][0:3]; //完整说明

                int array [8][4];    //紧凑说明

                array[7][3] = 1;    //设置最后一个元素值

注意:从越界地址读取数据,那么SV将返回数组元素类型缺省值,例如对于logic返回X,对于int或bit返回0。

  • 初始化和赋值  

                int ascend[4]='{0,1,2,3}; 

                int descend[5];

                descend='{4,3,2,1,0};  //先定义再初始化

                descend [0:2]='{5,6,7}; //为前三个元素赋值

                ascend='{4{8}}       //重复操作

                descend='{9,8,default:-1};  //{9,8,-1,-1,-1},default定义剩下的元素

                int md[2][3]='{'{0,1,2,3},'{3,4,5}}; //定义多维数组

  • 非合并数组

                bit [7:0]barray[3];    //非合并数组,三行,每一行有一个8bit数据

  • 合并数组

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

                bit [3:0][7:0]barray;       //合并数组,一行,3个字节组成的32bit

                bit [3:0][7:0]barray[3];   //合并,3行,3*32bit

                barray[0]=lw

                barray[0][3]=8'h01;

                barray[0][1][6]=1'b1;

                nibbles=barray[0];         //复制合并数组的元素值32bit

  • 基本数组操作

  • for和foreach

                bit[31:0] src[5],dst[5];

                for(int i=0;i<$size(src);i++)  //$size(src)默认同于$size(src,1)为5,$size(src,2)为32。

                       src[i]=i;

                foreach(dst[j])                     //多维数组foreach(md[i,j])

               dst[j]=src[j]*2;

  • 赋值:=

  • 比较:==,!=   

注意:绿皮书知识点$display(“src%sdst”,(src==dst)?“==”:“!=”)


四、动态数组

        相较于定宽数组类型的宽度编译时就已经确定,动态数组则是在仿真运行时灵活调节数组的大小,因此需要‘[]’声明,并在运行时使用new[]分配空间。

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

                initial begin

                     dyn=new[5];            //分配空间

                     foreach(dyn[i])

                            dyn[i]=i;           //元素初始化

                 d2=dyn;                      //复制

                d2[0]=5;

                $display(dyn[0],d2[0]);

                dyn=new[20](dyn);       //分配20个空间,并进行复制

                dyn=new[100];            //重新赋值100个,旧值消失

                dyn.delete();               //也可以用new[0]

                end

注意:声明常数数组又不想统计元素个数时,对比定宽数组int dyn[3]='{1,2,3},动态数组

int dyn[]='{1,2,3} SV自动统计元素个数,避免了宽度指定错误的问题。

  • 数组定位

  • 方法定位

                tq=q.min();

                tq=d.max();

                tq=f.unique(); //唯一值的队列

  • with(指示sv如何搜索)

               int d[]='{9,1,8,3,4,4}, tq[$];

               tq=d.find with(item>3);             //找出大于三的元素

               tq=d.find_index with(item>3);  //{0,2,4,5}找出大于三元素的位置

               tq=d.find_index_first with(item>3); //{0}

               int count,d[] = '{9,1,8,3,4,4}

               count=d.sum with(item>7)       //count值为2,有{9,8}大于7。

  • 重复参数声明,意思相同

                tq=d.find_first with(item==4);

                tq=d.finf_first()with(item==4);

                tq=d.finf_first(x)with(x==4);

                tq=d.finf_first(item)with(item==4);

  • 数组排序

                int d[]='{9,1,8,3,4,4};

                d.reverse();                         //'翻转

                d.sort();                              //从小到大

                d.rsort();                             //从大到小

                d.shuffle();                          //随机放


五、队列

        结合了链表和数组的优点,可以在任何地方添加和删除元素,并且通过索引对任一元素访问,不像链表去遍历目标元素之前的所有元素,当元素增加到超过原有空间容量时,SV会自动分配更多空间。队列元素编号0到$。

  • 利用队列函数

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

                   initial begin

                       q.insert(1,j);               //在2之前插入1

                       q.insert(3,q2);           //在q中插入一个队列

                       q.delete(1)                //删除第1个元素

     

                       q.push_front(6);  //在队列最前面插入6

                       q.push_back(8);  //在队列最后面插入8

                       j=q.pop_back();  //取出队列最后面的数并赋值给j

                       j=q.pop_front();  //取出队列最前面的数并赋值给j

                       foreach(q[i])       //打印队列

                              $display(q[i]);

                       q.delete();

                       end

  • 利用队列操作

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

                    initial begin

                    q={q[0],j,q[1:$]}; //利用队列

                    q={q[0],q[2:$]);

                    q={6,q};

                     j = q[$];             //等同于取最后一个

                     q=q[0:$-1]        //从队伍末尾取出所有数据赋值给q

                     q={q,8};            //在队伍末尾插入数据

                     q={};                 //删除整个队列

                     end

注意:$放在范围表达式左边表示最小值,放在右边表示最大值。


六、关联数组

        动态数组的限制在于其储存空间在一开始就被固定下来,关联数组可以用来保存稀疏矩阵的元素,该数组只为实际写入的元素分配空间。

initial begin

       bit[63:0] assoc[bit[63:0]], idx=1;       //索引类型

              repeat(64)begin                        //对稀疏分布的元素初始化

              assoc[idx]=idx;

              idx=idx<<1;

              end

              foreach(assoc[i])  //使用foreach遍历数组,i不一定是1,2,4,8 顺序可能会变

七、结构体 struct

                        Struct功能较少,只是一个数据的集合,通常适用的方式是将若干相关的变量组合到一个struct结构定义中,伴随typedef可以用来创建新的类型,并利用新类型声明更多变量。

        typedef struct {int a;byte b;shortint c;int d;}my_struct_s;  //创建有四个成员变量的结构体

        my_struct_s st;                                                              //声明变量

        st='{32'haaa_aaaad, 8'hbb,16'hcccc, 32'hdddd_dddd};   //结构体赋值

        my_struct_s st='{32'haaa_aaaad, 8'hbb,16'hcccc, 32'hdddd_dddd}; //声明变量并结构体赋值

注意:数据非连续存放用“单引号”

八、枚举类型enum

        规范的操作码和指令例如ADD、WRITE等有利于代码的编写和维护,它比直接使用’h01可读性和维护性更好。枚举类型enum经常和typedef搭配使用,便于用户自定义枚举类型的共享使用。枚举类型可以自动为列表中的每个名称分配不同的数值。

        Typedef enum {INIT,DECODE,IDLE} fsmstate_e;  //创建代表0,1,2的数据类型

        fsmstate_e pastate,nstate;                                     //声明自定义类型变量

        initial begin

               case(pastate)

                      IDLE: nstate=INIT;                                    //数据赋值

                      INIT: nstate =DECODE;

                      default:nstate= IDLE;

                endcase

        end

注意: INIT=enum 右侧是枚举类型,可以赋值给整型,enum=T’(INT) 右侧是整型,要先转化成枚举类型,因为例如上面的fsmstate_e,当整数为3,4,5等无法赋值给nstate,编译失败。

九、字符串

字符串声明string s

                string s;                                          //声明

                initial begin

                       s="IEEE ";                               //初始化

                       $display(s.getc(0));                 //I

                       s.putc(s.len()-1,"-"); //将最后一个元素“一个空格”变成“-”  //字符串用len()表示长度

                       s={s,"P1800"};    //链接字符   IEEE-P1800

                       $display(s.substr(2,5));  //显示EE-P

                 end

                task my_log(string message);          //传入一个字符串变量

                              $display("@%0t:%s",$time,message);

                endtask

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值