【SV】枚举类型

1.1. 用户自定义类型(typedef)

局部typedef定义:只用于设计的特定部分时,typedef的定义可在module或interface中

共享typedef定义:当在多个模型中使用时,typedef的定义可在包中进行,module,interface,program block可以通过导入packet子项来使用typedef定义

例如:

package chip_types;
 
`ifdef TWO_STATE
  typedef bit dtype_t;  //当宏定义TWO_STATE时定义dtype_t为bit类型
`else
  typedef logic dtype_t;
`endif
 
endpackage
 
import chip_types::dtype_t; // import 定义 into $unit
 
module counter(
  output dtype_t [15:0] count,
  input  dtype_t clock, resetN
);
    ...
 
endmodule
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
module ALU

(input definitions::instruction_t IW,                           //用范围解析操作符::引用definitions包中的instruction_t结构体,并对其命名为IW

input logic clock,

output logic [31:0] result

);

always_ff @(posedge clock) begin

case (IW.opcode)

definitions::ADD : result = IW.a + IW.b; //用范围解析操作符::引用definitions包中的枚举ADD

definitions::SUB : result = IW.a - IW.b;

definitions::MUL : result = definitions::

multiplier(IW.a, IW.b);

endcase

end

endmodule

1.2. 枚举数据类型(enum)

使用枚举enum:

package chip_types;
 
  typedef enum {
    FETCH, WRITE, ADD, 
    SUB,MULT, DIV, SHIFT, NOP 
  } instr_t;
 
  //用户自定义枚举类型instr_t
 
endpackage
 
import chip_types::*; //import包定义到$unit编译单元域
 
module controller (input instr_t instruction,...);       //input instr_t类型instruction
 
  enum {WAITE, LOAD, STORE} State, NextState;    //枚举类型State, NextState,
  //他俩的值只能是{}中的label
 
  always_comb begin
    if(State == LOAD && instruction == FETCH)  //使用label
    ...
  end
 
endmodule

从包中导入enum时,一般用*导入整个包或者显式导入每个标签。

1.3. 枚举类型标签序列

state //创建单个标签state

state[N] // 创建标签序列 state0,state1, … stateN-1

state[N:M] //创建标签序列,由stateN开始,到stateM(正反向不存在)

1.4. 枚举类型标签作用域

  • enum列表中的label在其作用域内必须是唯一的(label唯一)

  • 这里的作用域包括:$unit, modules, interfaces, programs,begin…end blocks, fork…join blocks, tasks and functions

1.5. 枚举类型值

枚举类型值在没有显示指定时,默认int从0自加。且label的值也要唯一(value唯一)
Example:

enum {A=1, B, C, X=24, Y, Z} list;             //A=1,B=2,C=3,X=24,Y=25,Z=26

1.6. 枚举类型的基类

枚举类型的默认基类(base type)是int,也可以对枚举类型的基类进行显示声明
Eg:
enum logic [1:0] {WAITE, LOAD, READY} state; //2位宽的枚举类型,四态基类
注意label数涉及到value的值,要与基类类型匹配。

1.7. 自定义枚举类型

typedef enum {WAITE, LOAD, READY} states_t;     //自定义枚举类型states_t
 
states_t state, next_state;  //声明枚举state,next_state

同类型枚举变量可以互相赋值

1.7. 枚举类型的专用系统任务(system tasks)和方法(method)

方法(method):SV提供了一些能自动处理enum的内置函数,调用方式(类似C++):

<enum_variable_name>.first:返回指定变量枚举列表的第一个成员的值

<enum_variable_name>.last:返回指定变量枚举列表的最后一个成员的值

<enum_variable_name>.next():从枚举变量的当前位置算起,返回后面第N个 成员的值。如果枚举变量当前值不在枚举变量列表中,则返回列表中第一 个成员的value。可缺省。缺省时返回枚举列表中下一个成员的值。

<enum_variable_name>.prev():从枚举变量的当前位置算起,返回前面第N个 成员的值。如果枚举变量当前值不在枚举变量列表中,则返回列表中最后 一个成员的value。可缺省。缺省时返回枚举列表中前一个成员的值。

<enum_variable_name>.num:返回变量的枚举列表中元素个数

<enum_variable_name>.name:返回枚举变量中代表这个value的字符串


module和interface可以用四种方式引用包中的定义和声明:

1. 用范围解析操作符” :: ”直接引用

2. 将包中特定子项导入(import)到module or interface中

3. 将通配符(*)导入包中的子项到module or interface

4. 将包中子项导入(通过import且可使用*)到$unit声明域中(module外)

编译单元声明(不可综合):

只作用于同时编译的源文件(每次编译为一个单元,多次编译之间互不影响)

SV允许在package, module, interface , program block 的外部进行声明。
这些外部声明在“编译单元域”(compilation-unit scope)中,并且对所有同时编译的module可见

编译单元contain:

  1. 时间单元和精度声明
  2. Variable declarations
  3. Net declarations
  4. Constant declarations
  5. User-defined data types, using typedef, enum or class
  6. Task and function definitions

可在$unit中声明的可综合结构有:

  1. typedef用户定义类型定义(最好放在package内)
  2. Automatic functions
  3. Automatic tasks
  4. parameter and localparam constants
  5. package import

建议:
1.枚举类型声明不要在 u n i t 空 间 进 行 声 明 , 声 明 在 命 名 包 中 进 行 2. 可 将 包 i m p o r t 到 unit空间进行声明,声明在命名包中进行 2.可将包import到 unit2.importunit
3.import语句要出现在package中子项被引用前

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值