写在前面
本文主要介绍了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 格式。
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