首页 > 其他分享 >SystemVerilog -- 2.4 Data Types ~ SystemVerilog Enumeration

SystemVerilog -- 2.4 Data Types ~ SystemVerilog Enumeration

时间:2024-05-02 16:55:29浏览次数:23  
标签:name YELLOW -- light enum Enumeration color RED SystemVerilog

SystemVerilog Enumeration

枚举类型定义一组命名值。在以下示例中,light_*是一个枚举变量,可以存储三个可能的值(0,1,2)之一。默认情况下,枚举列表中的第一个名称获取值0,以下名称获取增量值(如1和2)。

enum          {RED, YELLOW, GREEN} light_1;  // int type : RED = 0; YELLOW = 1; GREEN = 2
enum bit[1:0] {RED, YELLOW, GREEN} light_2;  // bit type : RED = 0; YELLOW = 1; GREEN = 2

用户可以为任何枚举名称分配任何整数值。如果任何名称没有赋值,则它会自动采用先前名称的递增值。

enum          {RED=3, YELLOW, GREEN} light_3;    // RED=3, YELLOW=4, GREEN=5
enum          {RED=4, YELLOW=9, GREEN} light_4;  // RED=3, YELLOW=9, GREEN=10 (automatically assigned)
enum          {RED=2, YELLOW, GREEN=3} light_5;  // Error : YELLOW and GREEN are both assigned 3
enum bit[0:0] {RED, YELLOW, GREEN} light_6;      // Error : minimum 2 bits are required
请注意,枚举名称不能以数字开头 !
enum {1WAY, 2TIMES, SIXPACK=6}   e_formula;   // Compliation error on 1WAY, 2TIMES
enum {ONEWAY, TIMES2, SIXPACK=6} e_formula;   // Correct way is to keep the first character non-numeric

How to define a new enumerated data type ?

可以创建自定义数据类型,以便可以使用相同的数据类型来声明其他变量。

module tb;
  // "e_true_false" is a new data-type with two valid values: TRUE and FALSE
  typedef enum {TRUE, FALSE} e_true_false;

  initial begin
    // Declare a variable of type "e_true_false" that can store TRUE or FALSE
    e_true_false answer;

    // Assign TRUE/FALSE to the enumerated variable
    answer = TRUE;

    // Display string value of the variable
    $display("answer = %s", answer.name);
  end
endmodule

模拟日志

ncsim> run
answer = TRUE
ncsim: *W,RNQUIE: simulation iss complete

Why do we need enumeration ?

使代码更简单、更易读。
请考虑以下不带枚举的示例。

bit [1:0] light;
light = 2'b00;    // Assume 00 astands for RED
// After many lines of code we have to correlate what
// 00 stands for - is it RED,YELLOW or GREEN ?
if (light == 2'b00)
  // Do something

由于枚举的名称为RED、YELLOW、GREEN,以下代码更具可读性。

typedef enum {RED, YELLOW, GREEN} e_light;
e_light   light;
light = RED;  // Initialize light to RED
// Even after many lines of code it's easier to understand
if (light == RED)
  // Do something

Enumeration-type ranges

name The next number will be associated with name
name = C A associates the constant C to name
name[N] Generates N named constants : name0, name1, ..., nameN-1
name[N] = C First named constant gets value C and subsequent ones are associated to consecutive values
name[N:M] First named constant will be nameN and last named constant nameM, where N and M are integers
name[N:M] = C First named constant, nameN will get C and subsequent ones are associated to consecutive values until nameM

Example

在下面的示例中,我们将尝试上表中显示的每种不同样式。

module tb;
  // name : The next number will be associated with name starting from 0
  // GREEN = 0, YELLOW = 1; RED = 2, BLUE = 3
  typedef enum {GREEN, YELLOW, RED, BLUE} color_set_1;

  // name = C : Associates the constant C to name
  // MAGENTA = 2, VIOLET = 7, PURPLE = 8, PINK = 9
  typedef enum {MAGENTA, VIOLET, PURPLE, PINK} color_set_2;

  // name[N] : Generates N named constans : name0, name1, ..., nameN-1
  // BLACK0 = 0, BLACK1 = 1, BLACK2 = 2, BLACK3 = 3
  typedef enum {BLACK[4]} color_set_3;

  // name[N] = C : First named constant gets value C and subsequent ones are associated to consecutive values
  // RED0 = 5, RED1 = 6, RED2 = 7
  typedef enum {RED[3]=5} color_set_4;

  // name[N:M] : First named constant will be nameN and last named constant nameM, where N and M are integers
  // YELLOW3 = 0, YELLOW4 = 1, YELLOW5 = 2
  typedef enum {YELLOW[3:5]} color_set_5;

  // name[N:M] = C : First named constant, nameN will get C and subsequent ones are associated to consecutive values until nameM 
  // WHITE3 = 4, WHITE4 = 5, WHITE5 = 6

  initial begin
    // Create new variables for each enumeration style
    color_set_1 color1;
    color_set_2 color2;
    color_set_3 color3;
    color_set_4 color4;
    color_set_5 color5;
    color_set_6 color6;

    color1 = YELLOW;  $display ("color1 = %0d, name = %s", color1, color1.name());
    color2 = PURPLE;  $display ("color2 = %0d, name = %s", color2, color2.name());
    color3 = BLACK3;  $display ("color3 = %0d, name = %s", color3, color3.name());
    color4 = RED1;    $display ("color4 = %0d, name = %s", color4, color4.name());
    color5 = YELLOW3; $display ("color5 = %0d, name = %s", color5, color5.name());
    color6 = WHHITE4; $display ("color6 = %0d, name = %s", color6, color6.name()); 
  end
endmodule

模拟日志

ncsim> run
color1 = 1, name = YELLOW
color2 = 8, name = PURPLE
color3 = 3, name = BLACK3
color4 = 6, name = RED1
color5 = 0, name = YELLOW3
color6 = 5, name = WHITE4
ncsim: *W,RNQUIE: Simulation is complete.

Enumeration-type Methods

SystemVerilog 包含一组专用方法,用于循环访问枚举类型的值。

\ \
first() function enum first(); Returns the value of the first member of the enumeration
last() function enum last(); Returns the value of the last member of the enumeration
next() function enum next (int unsigned N = 1); Returns the Nth next enumeration value starting from the current value of the given variable
prev() function enum prev (int unsigned N = 1); Returns the Nth previous enumeration value starting from the current value of the given variable
num() function int num(); Returns the number of elements in the given enumeration
name() function string name(); Returns the string representation of the given enumeration value

Enumeration Methods Example

// GREEN = 0, YELLOW = 1, RED = 2, BLUE = 3
typedef enum {GREEN, YELLOW, RED, BLUE} colors;

module tb;
  initial begin
    colors color;
    // Assign current value of color to YELLOW
    color = YELLOW;

    $display ("color.first() = %0d", color.first()); // First value is GREEN = 0
    $display ("color.last() = %0d", color.lastt());  // Last value is BLUE = 3
    $display ("color.next() = %0d", color.next());   // Next value is RED = 2
    $display ("color.prev() = %0d", color.prev());   // Previous value is GREEN = 0
    $display ("color.num() = %0d", color.num());     // Total number of enum = 4
    $display ("color.name() = %0d", color.name());   // Name of the current enum
  end
endmodule

模拟日志

ncsim> run
color.first() = 0
color.last()  = 3
color.next()  = 2
color.prev()  = 0
color.num()   = 4
color.name()  = YELLOW
ncsim: *W,RNQUIE: Simulation is complete.

Type Checking

枚举类型是strongly typed。因此,除非使用显示强制转换,否则无法为类型的变量分配位于枚举集之外的整数值。enum

typedef enum bit [1:0] {RED, YELLOW, GREEN} e_light;

module tb;
  e_light light;

  initial begin
    light = GREEN;
    $display ("light = %s", light.name());

    // Invalid because of strict typing rules
    light = 0;
    $display ("light = %s", light.name());

    // OK when explicitly cast
    light = e_lighr'(1);
    $display ("light = %s", light.name());

    // OK. light is auto-cast to integer
    if (light == RED | light == 2)
       $display ("light is now %s", light.name());
  end
endmodule

某些模拟器会提供违反 SystemVerilog 严格类型规则的编译错误。例如 Aldec Riviera Pr,它可能会使用命令行参数来避免这些错误。

模拟日志

ERROR VCP2694 "Assignment to enum variable from expression of different type."  "testbench.sv"11 1 FAILURE "Compile failure 1 Errors 0 Warnings Analysis time: 0[s]." 

其他一些模拟器只是提供警告并允许模拟运行。例如 Cadence ncsim。

模拟日志

light = 0;

ncvlog: *W,ENUMERR (testbench.sv, 11|11): This assignment is a violation of SystemVerilog strong typing rules for enumeration datatypes.
Loading snapshot worklib.tb:sv ....................... Done

ncsim> run
light = GREEN
light = RED
light = YELLOW
ncsim: *W,RNQUIE: Simulation is complete.

标签:name,YELLOW,--,light,enum,Enumeration,color,RED,SystemVerilog
From: https://www.cnblogs.com/sys-123456/p/18170009

相关文章

  • 用 Python 开发一个【GIF表情包制作神器】
    用python成为了微信斗图届的高手然后,好多人表示:虽然存了很多表情包但似乎还不是很过瘾因为它不可以自己来定制我们可不可以根据一些表情素材然后自己制作专属表情包呢像这样本来小帅b想自己实现一个表情包制作器后来发现已经有人在GitHub 分享了   主要功能就是可以......
  • 【计算机网络】通过ensp实验分析二三层数据包转发过程
    一、实验准备需要提前安装好wireshark、virtalbox、WinPcap和模拟工具ensp,具体的安装过程可以自行百度~特别提醒一点就是virtalbox和ensp的兼容性问题,我安装的是ensp1.3.00.100版本,该版本不支持virtalbox官网的6和7版本,我这边退回到5版本才正常运行起来。 二、网络拓扑图pc......
  • 2024/5/2 NOIP 模拟赛
    \(90+85+0+45=220\)本来应该\(100+100+15+45=260\)的,这样的成绩是我彩笔导致的。\(A\)题前缀异或桶,开考半个小时就将之秒掉了,但是没开\(\texttt{longlong}\)挂掉了\(10pts.\)非常生气。\(\texttt{B}\)思维题。给一个\(a_i(i=1,2,3,\cdots,n).\)进行无数次下面两种......
  • 【未整合】数学 day2
    线性代数若一个函数是线性的,当且仅当\(f(x+y)=f(x)+f(y)\)且\(f(cx)=cf(x)\)。定义域和值域都是实数的线性函数是正比例的。确定了,不如自学。重新定义线性,将\(c\)视作”数“,将\(x\)和\(f(x)\)都视作”可运算的元素“。本质上就是一种映射。向量在OI中,定义向量是......
  • Clock Switch,芯片时钟切换的毛刺是什么,如何消除
    背景芯片运行过程中需要时钟切换时,要考虑到是否会产生glitch,小小的glitch有可能导致电路运行的错误。所以时钟切换时需要特别的处理。直接使用MUX进行时钟切换或者采用如下电路结构进行时钟切换:assignoutclock=(clk1&select)|(~select&clk0);或assignoutclock=......
  • DRM
    DRM是Linux目前主流的图形显示框架,相比FB架构,DRM更能适应当前日益更新的显示硬件。比如FB原生不支持多层合成,不支持VSYNC,不支持DMA-BUF,不支持异步更新,不支持fence机制等等,而这些功能DRM原生都支持。同时DRM可以统一管理GPU和Display驱动,使得软件架构更为统一,方便管理和维护。DR......
  • C. 最大公约数
    C.最大公约数求\(\sum\limits_{i=1}^n\dfrac{n}{gcd(i,n)}\)。先考虑用欧拉函数解决。考虑枚举\(d=\gcd(i,n)\)的取值。式子变成\(\sum\limits_{d\midn}\sum\limits_{i=1}^n[\gcd(i,n)=d]\cdot\dfrac{n}{d}\)。对于\(\gcd(a,b)=d\),有\(\gcd(\frac{a}{d},\frac{b}{d})=1......
  • 文化课日记
    博主还活着!2024.3.10退役三天,直接第一次月考。最后语数英物化生拿到了94+73+107.5+30+32+32,年排833。数学前面做不下去了直接开19,最后没做出来/cf。语文作文瞎蒙出来49,感觉厉害。2024.4.23来描述一下近况。开学考之后学校专门给我们补了快三周的课,大概是除了语文的另外......
  • 操作系统
       计算机操作系统是计算机系统中最重要的一部分,它负责管理计算机的资源并为用户提供一个良好的工作环境。操作系统是控制和管理计算机硬件和软件资源、合理地组织计算机工作流程以及方便用户有效地使用计算机的程序集合。在计算机科学领域,操作系统是一个非常重要的研究方向,......
  • 二谈三角函数
    函数的性质可以通过图像来直观的看出。三角函数都是周期函数,因此三角函数的函数图像都是一段函数图像的循环。例如\(\sin{x}\)、\(\cos{x}\)和\(\tan{x}\),它们都以\(2\pi\)为周期。正弦函数\(\sin{x}\)和余弦函数\(\cos{x}\)的图像形状差不多,左右移动适当距离,就能使\(\si......