0
点赞
收藏
分享

微信扫一扫

spinal HDL - 03 - Spinal HDL数据类型 - 复合数据类型


写在前面

本文主要介绍了spinal HDL语言的复合数据类型,主要对Bundle、Vec进行介绍,同时对UFix/SFix进行了介绍。

Bundle

​Bundle​​​是复合类型,根据单个名称定义了一组命名的信号的(任何SpinalHDL基本类型)。​​Bundle​​可用于对数据结构、总线和接口进行建模。

声明

声明包的语法如下:

case class myBundle extends Bundle {
val bundleItem0 = AnyType
val bundleItem1 = AnyType
val bundleItemN = AnyType
}

例如,一个包含颜色的包可以定义为:

case class Color(channelWidth: Int) extends Bundle {
val r, g, b = UInt(channelWidth bits)
}

运算操作

以下运算符可用于该​​Bundle​​类型:

Operator

Description

Return type

x === y

相等

Bool

x =/= y

不相等

Bool

类型转换

Operator

Description

Return

x.asBits

二进制转换为Bits

Bits(w(x) bits)

val color1 = Color(8)
val myBits := color1.asBits

将 Bits 转换回 Bundle

该​​.assignFromBits​​​操作可以被看作是​​.asBits​​相反的操作。

Operator

Description

Return

x.assignFromBits(y)

转换Bits (y) 为 Bundle(x)

Unit

x.assignFromBits(y, hi, lo)

转换 Bits (y) 为 Bundle(x)具有高/低边界

Unit

以下示例将名为 CommonDataBus 的 Bundle 保存到循环缓冲区(第 3 方内存)中,稍后读取位并将它们转换回 CommonDataBus 格式。

spinal HDL - 03 - Spinal HDL数据类型 - 复合数据类型_进制转换

case class TestBundle () extends Component {
val io = new Bundle {
val we = in Bool()
val addrWr = in UInt (7 bits)
val dataIn = slave (CommonDataBus())

val addrRd = in UInt (7 bits)
val dataOut = master (CommonDataBus())
}

val mm = Ram3rdParty_1w_1rs (G_DATA_WIDTH = io.dataIn.getBitsWidth,
G_ADDR_WIDTH = io.addrWr.getBitsWidth,
G_VENDOR = "Intel_Arria10_M20K")

mm.io.clk_in := clockDomain.readClockWire
mm.io.clk_out := clockDomain.readClockWire

mm.io.we := io.we
mm.io.addr_wr := io.addrWr.asBits
mm.io.d := io.dataIn.asBits

mm.io.addr_rd := io.addrRd.asBits
io.dataOut.assignFromBits(mm.io.q)
}

IO方向

在组件的 IO 定义中定义 Bundle 时,需要指定其方向。

如果 bundle 的所有元素都在同一个方向,你可以使用 in(MyBundle()) 或 out(MyBundle())。

val io = new Bundle {
val input = in (Color(8))
val output = out(Color(8))
}

master/slave

如果您的接口遵循主/从拓扑,则可以使用 ​​IMasterSlave​​​ 特性。 然后你必须实现函数 ​​def asMaster(): Unit​​​ 来从 master 的角度设置每个元素的方向。 然后你可以在 IO 定义中使用 ​​master(MyBundle())​​​ 和 ​​slave(MyBundle())​​ 语法。

case class HandShake(payloadWidth: Int) extends Bundle with IMasterSlave {
val valid = Bool()
val ready = Bool()
val payload = Bits(payloadWidth bits)

// You have to implement this asMaster function.
// This function should set the direction of each signals from an master point of view
override def asMaster(): Unit = {
out(valid, payload)
in(ready)
}
}

val io = new Bundle {
val input = slave(HandShake(8))
val output = master(HandShake(8))
}

Vec

Vec 是一种复合类型,它在单个名称下定义一组索引信号(任何 SpinalHDL 基本类型)。

声明

Declaration

Description

Vec(type: Data, size: Int)

创建一个能够容纳“数据”类型的“大小”元素的向量

Vec(x, y, …)

创建一个向量,其中索引指向提供的元素。此构造函数支持混合元素宽度。

示例

// Create a vector of 2 signed integers
val myVecOfSInt = Vec(SInt(8 bits), 2)
myVecOfSInt(0) := 2
myVecOfSInt(1) := myVecOfSInt(0) + 3

// Create a vector of 3 different type elements
val myVecOfMixedUInt = Vec(UInt(3 bits), UInt(5 bits), UInt(8 bits))

val x, y, z = UInt(8 bits)
val myVecOf_xyz_ref = Vec(x, y, z)

// Iterate on a vector
for(element <- myVecOf_xyz_ref) {
element := 0 // Assign x, y, z with the value 0
}

// Map on vector
myVecOfMixedUInt.map(_ := 0) // Assign all elements with value 0

// Assign 3 to the first element of the vector
myVecOf_xyz_ref(1) := 3

运算操作

以下运算符可用于该​​Vec​​类型:

比较操作

Operator

Description

Return type

x === y

相等

Bool

x =/= y

不相等

Bool

示例

// Create a vector of 2 signed integers
val vec2 = Vec(SInt(8 bits), 2)
val vec1 = Vec(SInt(8 bits), 2)
myBool := vec2 === vec1 // Compare all elements

类型转换

Operator

Description

Return

x.asBits

二进制转化为Bits

Bits(w(x) bits)

示例

// Create a vector of 2 signed integers
val vec1 = Vec(SInt(8 bits), 2)
myBits_16bits := vec1.asBits

其他

Operator

Description

Return

x.getBitsWidth

返回 Vec 的完整大小

Int

示例

// Create a vector of 2 signed integers
val vec1 = Vec(SInt(8 bits), 2)
println(vec1.getBitsWidth) // 16

UFix/SFix

UFix 和 SFix 类型对应于可用于定点算术的位向量。

声明

声明定点数的语法如下:

Unsigned Fixed-Point

Syntax

bit width

resolution

max

min

UFix(peak: ExpNumber, resolution: ExpNumber)

峰值分辨率

2^分辨率

2peak-2resolution

0

UFix(peak: ExpNumber, width: BitCount)

宽度

2^(峰宽)

2peak-2(peak-width)

0

Signed Fixed-Point

Syntax

bit width

resolution

max

min

SFix(peak: ExpNumber, resolution: ExpNumber)

峰值分辨率+1

2^分辨率

2peak-2分辨率

-(2^peak)

SFix(peak: ExpNumber, width: BitCount)

宽度

2^(峰宽-1)

2peak-2(peak-width-1)

-(2^peak)

格式

所选格式遵循使用 Q 表示法定义定点数格式的常用方法。例如 Q8.2 将表示 8+2 位的定点数,其中 8 位用于自然部分,2 位用于小数部分。如果定点数是有符号的,则多使用一位作为符号。分辨率定义为可以用这个数字表示的 2 的最小幂。

为了使表示 2 的幂的数字更不容易出错,在​​spinal.core​​​called 中有一个数字类型,​​ExpNumber​​​用于定点类型构造函数。这种类型的便利包装器以​​exp​​函数的形式存在(在本页的代码示例中使用)。

示例

// Unsigned Fixed-Point
val UQ_8_2 = UFix(peak = 8 exp, resolution = -2 exp) // bit width = 8 - (-2) = 10 bits
val UQ_8_2 = UFix(8 exp, -2 exp)

val UQ_8_2 = UFix(peak = 8 exp, width = 10 bits)
val UQ_8_2 = UFix(8 exp, 10 bits)

// Signed Fixed-Point
val Q_8_2 = SFix(peak = 8 exp, resolution = -2 exp) // bit width = 8 - (-2) + 1 = 11 bits
val Q_8_2 = SFix(8 exp, -2 exp)

val Q_8_2 = SFix(peak = 8 exp, width = 11 bits)
val Q_8_2 = SFix(8 exp, 11 bits)

赋值操作

当没有比特丢失时,对定点值的赋值是有效的。任何位丢失都会导致错误。如果源定点值太大,该​​.truncated​​函数将允许您调整源数字的大小以匹配目标大小。

示例

val i16_m2 = SFix(16 exp, -2 exp)
val i16_0 = SFix(16 exp, 0 exp)
val i8_m2 = SFix( 8 exp, -2 exp)
val o16_m2 = SFix(16 exp, -2 exp)
val o16_m0 = SFix(16 exp, 0 exp)
val o14_m2 = SFix(14 exp, -2 exp)

o16_m2 := i16_m2 // OK
o16_m0 := i16_m2 // Not OK, Bit loss
o14_m2 := i16_m2 // Not OK, Bit loss
o16_m0 := i16_m2.truncated // OK, as it is resized
o14_m2 := i16_m2.truncated // OK, as it is resized

Scala常量

在分配给 UFix 或 SFix 信号时,Scala BigInt 或 Double 类型可用作常量。

val i4_m2 = SFix(4 exp, -2 exp)
i4_m2 := 1.25 // Will load 5 in i4_m2.raw
i4_m2 := 4 // Will load 16 in i4_m2.raw

原始值

可以使用该​​raw​​属性读取或写入定点数的整数表示。

val UQ_8_2 = UFix(8 exp, 10 bits)
UQ_8_2.raw := 4 // Assign the value corresponding to 1.0
UQ_8_2.raw := U(17) // Assign the value corresponding to 4.25

运算操作

以下运算符可用于该​​UFix​​类型:

算术运算

Operator

Description

Returned resolution

Returned amplitude

x + y


Min(x.resolution, y.resolution)

Max(x.amplitude, y.amplitude)

x - y


Min(x.resolution, y.resolution)

Max(x.amplitude, y.amplitude)

x * y


x.resolution * y.resolution)

x.amplitude * y.amplitude

x >> y

算术右移, y : Int

x.amplitude >> y

x.resolution >> y

x << y

算术左移, y : Int

x.amplitude << y

x.resolution << y

x >>| y

算术右移, y : Int

x.amplitude >> y

x.resolution

x <<| y

算术左移, y : Int

x.amplitude << y

x.resolution

Comparison

Operator

Description

Return type

x === y

相等

Bool

x =/= y

不相等

Bool

x > y

大于

Bool

x >= y

大于等于

Bool

x > y

小于

Bool

x >= y

小于等于

Bool

类型转换

Operator

Description

Return

x.asBits

二进制转换为 Bits

Bits(w(x) bits)

x.asUInt

二进制转换为 UInt

UInt(w(x) bits)

x.asSInt

二进制转换为 SInt

SInt(w(x) bits)

x.asBools

转换成 Bool 数组

Vec(Bool,width(x))

x.toUInt

返回对应的 UInt(带截断)

UInt

x.toSInt

返回对应的 SInt(带截断)

SInt

x.toUFix

返回对应的 UFix

UFix

x.toSFix

返回对应的SFix

SFix

其他

Name

Return

Description

x.maxValue

返回可存储的最大值

Double

x.minValue

返回可存储的最小值

Double

x.resolution

x.amplitude * y.amplitude

Double

Reference

  1. spinal HDL官方文档


举报

相关推荐

0 条评论