用户自定义和枚举数据类型

用户自定义和枚举数据类型

用户自定义
1、typedef定义用户自定义类型
SystemVerilog同C一样,使用typedef关键字来建立用户自定义类型。用户自定义类型允许使用现有的数据类型建立新的数据类型。新的数据类型定义后,可以声明这个类型的变量

typedef int unsigned uint;
...
unint a,b;//unint类型的两个变量

2、局部使用typedef
用户自定义类型可以在局部定义,也可以在编译单元域进行外部定义。当一个用户自定义数据类型只用于设计的特定部分时,typedef的定义可以在模块或者设计的接口部分。

module alu(...);typedef logic[3:0] nibble;nibble opA,opB;//nibble类型的变量nibble [7:0] data;//由8个nibble类型组成的32位向量

3、共享typedef定义
(1)包中的typedef定义
如果一个用户自定义类型会在很多不同的模型中用到,那么typedef声明可以在包中内声明。然后这些定义就可以被直接引用,或导入到每个使用该用户自定义类型的模块、接口或程序块中。
(2)$unint中的typedef
typedef定义也可在外部,即编译单元域中声明。外部声明就是将typedef语句放在任何模块、接口或程序块的外面。

//直接从包中引用用户自定义类型
package chip_types;`ifdef TWO_STATEtypedef bit dtype_t;`elsetypedef logic dtype_t;`endif
endpackage
module counter
(output chip_types::dtype_t[15:0] count,input chip_types::dtype_t clock,resetN
); 
always@(posedge clock , negedge resetN)if(!resetN)  count <= 0;else count <= count +1;
endmodule

将包定义导入到$unint
当模块多个端口都是用户自定义类型,而每个端口声明直接引用包名又显得繁琐时,可以用这一方法。

//将包中的typedef 定义导入到$unint中
package chip_types;`ifdef TWO_STATEtypedef bit dtype_t;`elsetypedef logic dtype_t;`endif
endpackage
import chip_types::dtype_t;//导入定义到$unint
module counter
(output dtype_t[15:0] count,input dtype_t clock,resetN
); 
always@(posedge clock , negedge resetN)if(!resetN)  count <= 0;else count <= count +1;
endmodule

如果包中包含许多typedef ,可以通过通配符导入到$unint中,而不是将包中特定子项导入到 $unint

import chip_types::*;//通配符导入

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

//变量RGB有red、green、bule三个值
enum {red,greed,bule} RGB;

枚举值通过标签来区别

enum{WAITE,LOAD,STORE}State,NextState;

枚举数据类型提供了一种方法将一个变量的值对应到一个有意义的标签上,这可以是模型或者测试代码更易读,也可以使代码更容易自成文档,并更容易纠错。

package chip_typed;typedef enum{FETCH,WRITE,ADD,SUB,MULT,DIV,SHIFT,NOP} instr_t;
endpackage
import chip_types::*;//导入包定义到$unint里
module controller(output logic read,write,input instr_t instruction,input wire clock,resetN
);
enum{WAITE,LOAD,STORE}State,NextState;
always_ff@(posedge clock,negedge resetN)if(!resetN) State <= WAITE;else State <= NextState;
always_comb
begincase(State)WAITE: NextState = LOAD;LOAD: NextState = STORE;STORE: NextState = WAITE;endcase
end
always_comb
beginread = 0;write = 0;if(State == LOAD && instruction == FETCH)read = 1;else if(State == STORE && instruction == WRITE)write = 1;
end
注意:导入枚举类型定义名时不会自动导入枚举值标签

2、枚举类型标签序列
指定一个枚举列表标签序列

state创建单个标签state
state[N]创建标签序列,state0,state1,…stateN
state[N:M]创建标签序列,由stateN开始,stateM结束。如果N小于M,序列由N增长至M。如果N大于M,序列由N减少至M
enum {RESET,S[5],W[6:9]}state;

3、枚举类型标签作用域
枚举标签必须唯一
枚举类型列表中的标签在其作用域内必须是唯一的。可以包含枚举类型声明的作用域包括编译单元、模块、接口、程序、begin…end块、fork…join块、任务和函数。
4、枚举类型值
枚举类型标签有一个默认值
缺省情况下,枚举类型列表中的标签代表的实际数值是一个int类型的整数。枚举列表中的第一标签表示数值0,第二个名称表示1,第三个表示数值2,以此类推
用户可以指定标签的值
SystemVerilog可以显示地说明枚举列表中的标签表示的数值。这允许抽象的枚举类型在需要时进行修改以便描述更具体的硬件特性。

//枚举列表中的每一个标签都有一个与其对应的整数值。
enum{
ONE = 0,
FIVE =5,
TEN =10
}state;

标签值必须是唯一
枚举列表中的各个标签必须具有唯一的值。如果有两个标签具有相同的值就会出现错误。

5、枚举类型的基类
枚举类型的默认基类为int类型
枚举类型是具有以系列标签值的变量或线网。因此,枚举类型具有一个Verilog或SystemVerilog基类。枚举类型的默认基类是int,它是32位两态类型。
基类可以显示定义
为了更具体的描述硬件,SystemVerilog允许对枚举类型的基类进行显示的声明

//1位宽的枚举类型,两态基类
enum bit{TURE,FALSE} Boolean;//2位宽的枚举类型,四态基类
enum logic[1:0] {WAIT,LOAD,READY}state;

枚举值宽度
如果对显示定义枚举类型的枚举标签赋值,那么这个值的宽度必须与基类宽度相符

enum logic[2:0] {WAIT =3'b001,LOAD = 3'b010,READY = 3'b100}state;

四态枚举类型
如果枚举值的基类是四态数据类型,将枚举标签赋为X或则Z是合法的。

enum logic{ON = 1'b1,OFF = 1'bZ}out;

6、自定义和匿名枚举
自定义枚举类型使用typedef定义
枚举类型可以声明为一个用户自定义类型。这提供了一个便捷方式来声明几个具有相同枚举值的变量或线网。由typedef声明的枚举类型一般称作自定义枚举类型,不使用typedef定义的则称作匿名枚举类型

typedef enum{WAITE,LOAD,REDAY}states_t;
states_t state,next_state;

7、枚举类型操作的强类型检验
大部分变量类型都是弱类型
也就是说,任何类型的任何值都可以赋给一个变量。数值将会自动地转换成变量的数据类型,遵循Verilog或SystemVerilog标准指定的转换原则。
枚举类型是强类型
枚举类型的类型是半强类型。一个枚举类型只可以进行下列赋值:

  • 枚举类型列表中的一个标签。
  • 同类枚举类型的其他变量(即用同样枚举类型声明的变量)
  • 通过cast转换成枚举类型变量的数值
    操作使用标签的基类
    当对一个枚举类型数据进行操作时,枚举数值自动转换成代表枚举类型列表中标签的基类和内部值。如果枚举类型标签的基类没有显式地声明,则默认基类和标签为int类型。
typedef enum {WAIT,LOAD,READY}states_t;
states_t state,next_state;
int foo;

8、将表达式强制转换为枚举类型
将值强制转换成枚举类型
一个操作的结果可以转换成一个枚举类型,然后赋给同种类型的一个枚举类型变量。SystemVerilog的强制转换操作符或者动态$cast系统函数都可以使用。

typedef enum {WAIT,LOAD,READY}states_t;
states_t state,next_state;
next_state = states_t(state+1); //合法的强制类型转换
$cast(next_state,state+1);  //合法的动态的$cast系统函数

强制转换操作符总是进行强制转换操作和赋值,而不检查被赋的值是否在枚举类型设置的合法范围内。
如果state有一个值READY,它代表2,加1结果为整数3.将这个数值赋给next_state将会超出next_state枚举类型列表的数值范围。
动态的$cast系统函数在修改目标变量之前检查表达式的结果是否是一个合法值。如果state加上1对于next_state是一个范围外的值,那么 $cast(next_state,state+1)不会修改next_state,并且会报告一个运行错误。
9、枚举类型的专用系统任务和方法
SystemVerilog提供了一些内置函数,称为方法(method),可以循环访问枚举类型列表中的值。这些方法能自动处理枚举类型的半强类型特性,使一些操作变得简单,如递增到枚举类型列表下一个值、跳到列表的开头、跳到列表的结尾。使用这些方法,不必知道列表的中的名称和值。
这些处理枚举列表的专用方法的调用方法类似于C++类方法的调用,即方法的名称附在在枚举变量名字的后面,用一个“.”分开。
<枚举变量名>.first --返回指定变量枚举列表中的第一个成员的值。
<枚举变量名>.last–返回枚举列表最后一个成员的值。
<枚举变量名>.next()–返回枚举列表中下一个成员的值。可以用一个整数值作为next的参数。在这种情况下,从枚举变量的当前位置算起,返回后面第N个成员的值。如果到达了枚举列表的末尾,则会返回到列表的开头。如果枚举变量的当前值不在枚举列表中,则返回列表中第一个成员的值。
<枚举变量名>.prev()–返回枚举列表中前一个成员的值。同next的方法一样。
<枚举变量名>.num–返回变量的枚举列表中元素个数
<枚举变量名>.name–返回枚举变量中代表这个值的字符串。如果这个值不在枚举变量列表中,则返回一个空字符串。

module confidence_counter(input logic synced,compare,resetN,clock,ouptut logic in_sync
);
enum{cnt[0:15]}State,Next;always_ff@(posedge clock , negedge resetN)if(!resetN) State <= cnt0;else State <= Next;always_comb
beginNext = State;//default NextState valuecase(State)cnt0:if(compare && synced) Next = State.next;cnt1:beginif(compare && synced) Next = State.next;if(compare && !synced) Next = State.first;endcnt15:if(compare && !synced) Next = State.prev(2);default:beginif(compare && synced) Next = State.next;if(compare && !synced) Next = State.prev(2);endendcase
endalways_ff@(posedge clock , negedge resetN)if(!resetN) in_sync <=0;else beginif(State == cnt8) in_sync <= 1;if(State == cnt0) in_sync <= 0;end

10、打印枚举类型
打印枚举类型标签和值
枚举类型值可以作为标签的内部值或标签名打印。直接打印枚举变量会打印变量的内部值。使用枚举类型的方法name可以读取当前值的标签名称,并返回包含名称的字符串这个字符串可以用$display打印出来。

module FSM(input logic clock,resetN,output logic[3:0]control);enun logic[2:0]{WAITE=3'b001,LOAD=3'b010,READY=3'b010} State,Next;always @(posedge clock, negedge resetN)if(!resetN)State<=WAITE;else State<=Next; 
always_comb begin$display("\nCurrent state is 8s(号b)",State.nane,State);case(State)WAITE:Next=LOAD;LOAD:Next=READY; READY:Next=WAITE; endcase$display("Next state will be 号s(告b)",Next.name,Next); endassign control=State;
endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/243298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Keyboard驱动介绍

Keyboard驱动介绍 最近手里面没啥事&#xff0c;就想看看一些Driver的MDD层。 以前改过Keyboard Driver的PDD层&#xff0c;但是对它的MDD层还真是一片空白&#xff0c;这两天随便看了看Keyboard的MDD层&#xff0c;赶紧把东西记录下来&#xff0c;以防以过段时间忘记了。 很多…

GDI+不同的地方

研究了GDI处理图像的地方&#xff0c;发现它一些与众不同的地方&#xff0c;被它坑了一天。。。。。1、GDI的像素的原点默认你在左下角的&#xff0c;所以读取像素的顺序是从最低一行开始的(bottom-left)&#xff0c;其他一般的图像处理软件&#xff0c;像Photoshop&#xff0c…

关于结构体的内容

关于结构体的内容 结构体使用类似于C语言的语法来定义 结构体使用struct关键字声明。结构体内的成员可以是任何数据类型&#xff0c;包括用户自定义类型和其他的结构体类型。 struct{int a,b; //32位变量opcode_t opcode;//用户定义类型logic [23:0] adress;//24位变量bit er…

Pushing Policy Failed because Checkpoint Firewall “Load on module failed – no memory”

One day when pushing firewall policy from Checkpoint management server to UTM 272 cluster gateways, it failed and I got error message “Load on module failed – no memory” on one of cluster members. “Network Security Policy ‘Montreal_DMZ’ was prepared …

电池驱动介绍

电池驱动介绍 一&#xff0e;整体框架 电池驱动代码量很小&#xff0c;可是麻雀虽小&#xff0c;五脏俱全。与其他的很多Driver一样&#xff0c;分为PDDMDD层&#xff0c;双层之间通过PDD的如下导出接口相联系。 Programming element Description BatteryDrvrGetLevels…

将1bpp的bmp图像存储为1bpp或者2bpp的tiff格式

// 将1bpp的位图转换为 1bit/2bit tiff /** 参数&#xff1a;BYTE *src 二值图像的像素数据&#xff0c;不包含头部信息&#xff0c; 1bpp, int src_width 原图的宽度, in pixles,int src_height 原图的高度, in pixlesint bpp 转换tiff指定的bpp */ static BYTE *BW2Tif(…

关于联合体的内容

关于联合体的内容 联合体只储存一个值 联合体只存储一个元素&#xff0c;但这个元素可以有多种表示方法&#xff0c;每种表示可以是不同的数据类型。 联合体的声明语法类似于结构体&#xff0c;联合体的成员的引用也跟结构体一样。 union{int i;int unsigned u; }data; ... d…

Point-BERT:一种基于Transformer架构的点云深度网络

目录 1. 前言 2. Point Tokenization 3. Transformer Backbone 4. Masked Point Modeling 5. Experiments Reference 1. 前言 从PointNet [1] 开始&#xff0c;点云深度网络逐渐成为解决点云特征提取与语义分析的主要研究方向。尤其在OpenAI的GPT模型获得了突破性成果后&#…

GNS3 VoIP Lab (Cisco 3725 and CME 4.3)

Here is a simple VoIP Lab in GNS3 environment. It is only used for my lab test and recorded here for future reference. 1. Topology: GNS3 Topology:Logic Topology:xp(192.168.2.60)——–C3725 Router(192.168.2.10) 2. Enviroment: ESXi 5.5 (or Vmware Workstation…

谁知道这个代码片段干嘛的

int value 0xAAAA;for (int i0; i<8; i){int tmp value & 0x3; // 取出第两个比特位置if (tmp 0x0){//}else if (tmp 0x1){//}else if (tmp 0x2){//}else if(tmp 0x3){TRACE0("???");}TRACE1("tmp0x%x\n\n", tmp);value >> 2;}

关于数组的内容

关于数组的内容 Verilog数组声明的基本语法 <data_type><vector_size><array_name><array_dimension> 例如&#xff1a; reg[15:0] RAM [0:4095];//储存器数组SystemVerilog允许任何数据类型的非压缩数组 SystemVerilog将非压缩数组的声明进行了扩展…

Touch Driver介绍

Touch Driver介绍 一&#xff0e;相关知识介绍 1&#xff0e;Touch Driver的加载过程 GWES到[HKEY_LOCAL_MACHINE/HARDWARE/DEVICEMAP/TOUCH]的“Driver name”获取Driver DLL的名字&#xff0c;如果没有找到该键值&#xff0c;则使用默认名字Touch.dll。 Touch Driver的加…

BreadCrumb控件

BreadCrumb控件&#xff0c;如上图所示&#xff0c;即面包屑导航控件&#xff0c;类似于TreeCtrl&#xff0c;但不是一次显示所有的Item&#xff0c;VC 2010可以编译通过&#xff0c;稍微修改一下其他的也可以编译&#xff0c;源代码下载&#xff1a; http://download.csdn.net…

foreach数组循环结构体

foreach数组循环结构体 foreach循环遍历任何维数的数组 Systemverilog增加了foreach循环&#xff0c;它可用来对一维或多维数组中的元素进行迭代&#xff0c;而不必指定数组每个维度的宽度。foreach循环的自变量是数组名&#xff0c;它后面是方括号内用逗号隔开的循环变量列表…

Android简介

最近Android很火&#xff0c;小弟也想了解一下它的结构。跟CE或者Mobile比起来&#xff0c;它的结构是有点凌乱&#xff0c;也难怪&#xff0c;毕竟是基于别人的内核在上层开发了一些应用 ---------------------------------------------------------------------------------…

说不尽的刘恒

认识刘恒快三十年了&#xff0c;作为曾经的同事和他小说的责任编辑&#xff0c;我只写过他一篇文章&#xff0c;还是在二十多年前。有时候特别熟悉的人反而不知道从何写起&#xff0c;因为一想起往事&#xff0c;各种记忆像开闸的水一样涌满眼前&#xff0c;让人很难落笔。1985…

印前处理的“发动机”——RIP

对于许多印刷厂来说&#xff0c;数字印前技术仍是个谜&#xff0c;尤其是光栅处理器RIP。除了RIP之处&#xff0c;我们也总听说打印机的内置控制单元。其实&#xff0c;RIP与内置控制单元在本质上是一样的&#xff0c;但也有所不同。听说起来好像有些玄乎&#xff0c;下面我们来…

组合逻辑过程块

组合逻辑过程块 always_comb代表组合逻辑 always_comb过程块表示建立组合逻辑模型 always_comb if(!mode)y a b; elsey a - b;always_comb能推断出其敏感表 与通用always过程块不同&#xff0c;always_comb块的后面不需要指明敏感表。软件工具已经知道设计的意图是建立一个…

外行看Flash的存储原理

突然在网上看到别人两年前写的一篇关于nor和nand的好文章&#xff0c;做为csdn的合法公民&#xff0c;有必要转 一、存储数据的原理 两种闪存都是用三端器件作为存储单元&#xff0c;分别为源极、漏极和栅极&#xff0c;与场效应管的工作原理相同&#xff0c;主要是利用电场的…

数码印刷

数码印刷 目前&#xff0c;RIP已经变成了印前生产的核心问题。它影响到从色彩和文件管理到印刷的整个生产过程的方方面面。而且&#xff0c;像陷印和拼大版这些以前需要单独的应用程序处理的功能&#xff0c;现在也被加到了RIP中。    新的RIP产品和销售商有很多。象Agfa,Ha…