【SystemVerilog学习笔记】4-用户自定义和枚举数据类型

本文详细介绍了SystemVerilog中typedef的用法,用于创建用户自定义类型,增强了代码的可读性和可维护性。同时,枚举类型在SystemVerilog中的引入使得变量的取值范围更加明确,提供了强类型检查。枚举类型可以指定标签序列,具有作用域限制,并且支持自定义和匿名枚举。此外,还讨论了枚举类型的值、类型、操作以及相关的系统任务和方法,强调了枚举类型在值和标签上的强类型特性。
摘要由CSDN通过智能技术生成


SystemVerilog对Verilog的拓展:

  • 使用typedef建立用户自定义类型。
  • 使用enum建立枚举类型。

4.1 typedef

  • 对比

    VerilogSystemVerilog
    主要用于RTL和门级建模,没有提供类似C语言的高级抽象建模的变量类型为系统级和体系结构级建模加入了许多新的数据类型,允许通过typedef关键字使用现有数据类型建立用户自定义类型

    例子:自定义类型

    typedef int unsigned uint;//利用现有数据类型(int unsigned)建立用户自定义类型(uint)
    ...
    uint a, b;
    
  • 用户自定义类型的位置:

    • 在局部定义。

    • 包内定义。

    • 编译单元域$unit.

    • 在包中定义然后导入到$uint。

      例子:在包中定义然后导入到$uint。

      //包声明
      package chip_types
          `ifdef TWO_STATE
              typedef bit dtype_t;
          `else
              typedef logic dtype_t;
          `endif
      endpackage
      //导入定义到$uint
      import chip_types::dtype_t;
      //模块声明
      module counter (
          output dtype_t[15:0]  count,
          input  dtype_t        clock   
      );
      always @(posedge clock, negedge resetN)
          if (!resetN)
              count <= 0;
          else
              count <= count + 1;
      endmodule
      
  • 命名习惯提示:使用“_t”作为用户自定义类型的结尾,增加代码可读性与便于维护。

4.2 枚举数据类型

  • 定义:
    枚举数据类型提供一种方式来声明一个具有特定允许值列表的抽象变量,每一个值都有一个确定的用户自定义的名字(label)。
    例子:

    //具有red, green, blue三个label的枚举变量RGB
    enum {red, green, blue} RGB;
    
  • 对比:

    VerilogSystemVerilog
    没有枚举类型,通过parameter或者宏定义实现标签值。无法限定信号的有效值(比如状态机的状态)的有效值仅仅是自定义的有效状态。增加了枚举类型,将一个变量的取值范围限制在有意义的label上。
  • 注意:

    • 当枚举类型定义从package中导入时,只有类型名被导入。
    • 为了使枚举类型的label可见,可以显式导入每个label,或者使用通配符导入。

4.2.1 指定枚举类型标签序列的方式:

方式说明
state创建单个名为state的标签。
state[N]创建名为state0,state1,…,stateN的标签序列。
state[N,M]N<M时,创建名为stateN,stateN+1,…,stateN的标签序列。N>M时,创建名为stateN,stateN-1,…,stateN的标签序列。

例子:

enum {RESET,S[5],W[6:9]} state;//label列表为:RESET,S0,...,S5,W6,...,W9。

4.2.2 枚举类型标签作用域:

枚举类型列表中的标签在同一个作用域必须是唯一的。

4.2.3 枚举类型值:

  • 缺省的情况下,从零开始递增。中间缺省的情况下,从前一个已说明的数值开始递增。
  • 允许显式说明值,但是值必须唯一。
    例子:
    enum {A,B,C=5,D,E} list;//标签值为:A=0,B=1,C=5,D=6,E=7。
    

4.2.4 枚举类型标签值的类型:

  • 默认为int类型。
  • 可以显示定义基类,但是标签值得符合基类得取值范围和位宽。
  • 如果X或者Z赋值给枚举列表中的一个标签,下一个标签必须显式赋值。以此类推,如果再下一个也没有显式赋值也必须显式赋值。
    例子:
    enum {A = 3'b001, B = 3'b010, C = 3'b100} list;//错误,位宽不对
    enum logic {A1 = 1'b0, B1, C1} list1;//错误,标签数超过基类所能代表得宽度。
    

4.2.5 自定义和匿名枚举

由typedef声明的枚举类型称为自定义枚举类型,不适用typedef定义的则称为匿名枚举类型。

4.2.6 枚举类型操作的强类型检验

  • 枚举类型合法的赋值:
    • 值为枚举类型列表中的一个标签。
    • 同类枚举类型的其他变量。
    • 通过cast系统函数转换成枚举类型变量的数值。

例子:

typedef enum {WAIT, LOAD, READY} state_t;
state_t state, next_state;
int foo;
foo = 1;
state = WAIT;//合法,值为枚举类型列表中的一个标签。
state = next_state;//合法,同类枚举类型的其他变量。
$cast(state, foo);//合法,通过cast系统函数转换成枚举类型变量的数值。

state = foo; //非法
state = state + 1;//非法
state++;//非法
next_state += state;//非法

4.2.8 枚举类型的专用系统任务和方法

  • <枚举变量名>.first;//返回第一个成员的值。
  • <枚举变量名>.last;
  • <枚举变量名>.next();//返回列表中下N个成员的值,如果到了末尾则会返回到列表开头。
  • <枚举变量名>.prev();
  • <枚举变量名>.num;//返回列表元素个数。
  • <枚举变量名>.num;//返回这个值对应的label,字符串。

4.2.9 打印枚举类型

$display("\nCurrent state is %s(%b)",state.name,state);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lu-ming.xyz

觉得有用的话点个赞吧 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值