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)
}
您可以在 Spinal HDL examples 中找到 APB3 definition 。
条件信号
Bundle
中的信号可以有条件地定义。除非 dataWidth
大于 0,否则在实力细化后的 myBundle``中将不会有 ``data
信号,如下例所示。
case class myBundle(dataWidth: Int) extends Bundle {
val data = (dataWidth > 0) generate (UInt(dataWidth bits))
}
备注
另请参阅 generate 了解有关此 SpinalHDL 方法的信息。
运算符
以下运算符可用于 Bundle
类型:
比较运算
运算符 |
描述 |
返回类型 |
---|---|---|
x === y |
等价性判断 |
Bool |
x =/= y |
不等价判断运算 |
Bool |
val color1 = Color(8)
color1.r := 0
color1.g := 0
color1.b := 0
val color2 = Color(8)
color2.r := 0
color2.g := 0
color2.b := 0
myBool := color1 === color2 // Compare all elements of the bundle
// is equivalent to:
// myBool := color1.r === color2.r && color1.g === color2.g && color1.b === color2.b
类型转换
运算符 |
描述 |
返回类型 |
---|---|---|
x.asBits |
二进制转换为 Bits |
Bits(w(x) bits) |
val color1 = Color(8)
val myBits := color1.asBits
线束中的元素将按其定义的顺序映射到位,按LSB 先放置的顺序。因此,color1
中的 r
将占据 myBits
的第 0 至 8 位(LSB),然后依次是 g
和 b
,b.msb
也是最终 Bits 类型的 MSB。
将位转换回线束
.assignFromBits
运算符可以被视为 .asBits
的逆操作。
运算符 |
描述 |
返回类型 |
---|---|---|
x.assignFromBits(y) |
将Bits (y)转换为Bundle(x) |
Unit |
x.assignFromBits(y, hi, lo) |
将Bits (y) 转换为具有高/低边界的 Bundle(x) |
Unit |
下面的示例将名为 CommonDataBus 的线束保存到循环缓冲区(第三方内存)中,随后读出比特,并将其转换回 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
时需要指定其方向。
in/out
如果线束的所有元素中的信号都朝同一方向传播,则可以使用 in(MyBundle())
or 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())
语法来使用。
有些函数定义为 toXXX,例如 Flow
类的 toStream
方法。这些函数通常可以由master端调用。另外,fromXXX函数是为slave侧设计的。通常master端可用的功能多于slave端。
例如:
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))
}