SpinalHDL之数据类型(四)

本文作为SpinalHDL学习笔记第五十七篇,介绍SpinalHDL的SpinalEnum数据类型。

目录:

1.描述(Description)

2.声明(Declaration)

3.操作符(Operators)

⼀、描述(Description)

Enumeration类型代表⼀组值组成的列表。

⼆、声明(Declaration)

枚举数据类型的声明⽅式如下:

object Enumeration extends SpinalEnum {
val element0, element1, ..., elementN = newElement()
}

对于上述例⼦, 使⽤默认的编码⽅式。原⽣的枚举类型⽤于VHDL, ⼆进制编码⽤于Verilog。
能够通过下述⽅式强制使⽤枚举编码:

object Enumeration extends SpinalEnum(defaultEncoding=encodingOfYourChoice) {
val element0, element1, ..., elementN = newElement()
}

Note:如果想为给定的模块定义枚举类型的输入/输出, 应该⽤如下⽅式定义:in(MyEnum())或者out(MyEnum)

1. 编码(Encoding)

SpinalHDL⽀持下述的枚举编码⽅式:

/*
*静态编码⽅式
*/
object MyEnumStatic extends SpinalEnum {
val e0, e1, e2, e3 = newElement()
defaultEncoding = SpinalEnumEncoding("staticEncoding")(
e0 -> 0,
e1 -> 2,
e2 -> 3,
e3 -> 7
)
/*
*⽤函数动态编码: _ * 2 + 1
*e.g. : e0 => 0 * 2 + 1 = 1
* e1 => 1 * 2 + 1 = 3
* e2 => 2 * 2 + 1 = 5
* e3 => 3 * 2 + 1 = 7
*/
val encoding = SpinalEnumEncoding("dynamicEncoding", _ * 2 + 1)
object MyEnumDynamic extends SpinalEnum(encoding) {
val e0, e1, e2, e3 = newElement()
}
}

 2. 举例(Example)

初始化枚举信号并给它赋值:

object UartCtrlTxState extends SpinalEnum {
val sIdle, sStart, sData, sParity, sStop = newElement()
}
val stateNext = UartCtrlTxState()
stateNext := UartCtrlTxState.sIdle
//你也可以import枚举类型使其元素可视化, 需要放在package⾥
import UartCtrlTxState._
stateNext := sIdle

Verilog:

localparam UartCtrlTxState_sIdle = 3'd0;
localparam UartCtrlTxState_sStart = 3'd1;
localparam UartCtrlTxState_sData = 3'd2;
localparam UartCtrlTxState_sParity = 3'd3;
localparam UartCtrlTxState_sStop = 3'd4;
wire [2:0] stateNext;
`ifndef SYNTHESIS
reg [55:0] stateNext_string;
`endif

`ifndef SYNTHESIS
always @(*) begin
case(stateNext)
UartCtrlTxState_sIdle : stateNext_string = "sIdle ";
UartCtrlTxState_sStart : stateNext_string = "sStart ";
UartCtrlTxState_sData : stateNext_string = "sData ";
UartCtrlTxState_sParity : stateNext_string = "sParity";
UartCtrlTxState_sStop : stateNext_string = "sStop ";
default : stateNext_string = "???????";
endcase
end
`endif
assign stateNext = UartCtrlTxState_sIdle;

三、操作符(Operators)

以下是可供Enumeration类型使⽤的操作符:

1. 比较运算(Comparison)

|操作符|描述|返回类型| |x===y|相等|Bool| |x=/=y|不相等|Bool|

import UartCtrlTxState._
val stateNext = UartCtrlTxState()
stateNext := sIdle
when(stateNext === sStart) {
...
}
switch(stateNext) {
is(sIdle) {
...
}
is(sStart) {
...
}
...
}

2. 类型(Types)

为了使⽤你的enum, 例如在函数⾥, 你需要它的类型。
enum中值的类型(例如sIdle的类型):

spinal.core.SpinalEnumElement[UartCtrlTxState.type]

或者等价地, 也可以如下⽅式:

UartCtrlTxState.E

bundle的类型(例如stateNext的类型):

spinal.core.SpinalEnumCraft[UartCtrlTxState.type]

或者等价地, 也可以⽤如下⽅式:

UartCtrlTxState.C

3. 类型转换(Type cast)

import UartCtrlTxState._
val stateNext = UartCtrlTxState()
myBits := sIdle.asBits
stateNext.assignFromBits(myBits)

 Verilog:

localparam UartCtrlTxState_sIdle = 3'd0;
localparam UartCtrlTxState_sStart = 3'd1;
localparam UartCtrlTxState_sData = 3'd2;
localparam UartCtrlTxState_sParity = 3'd3;
localparam UartCtrlTxState_sStop = 3'd4;
wire [2:0] myBits;
wire [2:0] stateNext;
wire [2:0] _zz_stateNext;
reg [7:0] counter;
`ifndef SYNTHESIS
reg [55:0] stateNext_string;
reg [55:0] _zz_stateNext_string;
`endif
`ifndef SYNTHESIS
always @(*) begin
case(stateNext)
UartCtrlTxState_sIdle : stateNext_string = "sIdle ";

UartCtrlTxState_sStart : stateNext_string = "sStart ";
UartCtrlTxState_sData : stateNext_string = "sData ";
UartCtrlTxState_sParity : stateNext_string = "sParity";
UartCtrlTxState_sStop : stateNext_string = "sStop ";
default : stateNext_string = "???????";
endcase
end
always @(*) begin
case(_zz_stateNext)
UartCtrlTxState_sIdle : _zz_stateNext_string = "sIdle ";
UartCtrlTxState_sStart : _zz_stateNext_string = "sStart ";
UartCtrlTxState_sData : _zz_stateNext_string = "sData ";
UartCtrlTxState_sParity : _zz_stateNext_string = "sParity";
UartCtrlTxState_sStop : _zz_stateNext_string = "sStop ";
default : _zz_stateNext_string = "???????";
endcase
end
`endif
assign myBits = UartCtrlTxState_sIdle;
assign _zz_stateNext = myBits;
assign stateNext = _zz_stateNext;

  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

千穹凌帝

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值