三态

在许多情况下,三态信号难以处理:

  • 它们不是真正的数字性

  • 除了IO之外,它们不用于数字设计

  • 三态概念并不自然地适合SpinalHDL内部图。

SpinalHDL为三态信号提供两种不同的抽象。 TriState 线束和 模拟信号和输入输出 信号。两者有不同的目的:

  • TriState应用于大多数目的,尤其是在设计中。该束包含一个附加信号来传递当前的方向。

  • Analoginout 应用于设备边界上的驱动以及其他一些特殊情况。有关更多详细信息,请参阅参考文档页面。

如上所述,推荐的方法是在设计中使用 TriState 。然后,在顶层, TriState 线束被赋值给模拟输入输出,以使综合工具推断出正确的I/O驱动。这可以通过 输入/出包装器 自动完成,或者根据需要手动完成。

三态

TriState线束定义如下:

case class TriState[T <: Data](dataType : HardType[T]) extends Bundle with IMasterSlave {
  val read,write : T = dataType()
  val writeEnable = Bool()

  override def asMaster(): Unit = {
    out(write,writeEnable)
    in(read)
  }
}

主端可以使用 read 信号读取外部值,使用 writeEnable 启用输出,最后使用 write 设置输出驱动的值。

这是一个使用示例:

val io = new Bundle {
  val dataBus = master(TriState(Bits(32 bits)))
}

io.dataBus.writeEnable := True
io.dataBus.write := 0x12345678
when(io.dataBus.read === 42) {

}

三态阵列

在某些情况下,您需要控制每个单独引脚的输出使能(像GPIO一样)。在这种情况下,您可以使用TriStateArray线束。

它的定义如下:

case class TriStateArray(width : BitCount) extends Bundle with IMasterSlave {
  val read,write,writeEnable = Bits(width)

  override def asMaster(): Unit = {
    out(write,writeEnable)
    in(read)
  }
}

它与TriState线束相同,不同的是 writeEnable 是一个位(Bits)来控制每个输出缓冲区。

这是一个用法示例:

val io = new Bundle {
  val dataBus = master(TriStateArray(32 bits)
}

io.dataBus.writeEnable := 0x87654321
io.dataBus.write := 0x12345678
when(io.dataBus.read === 42) {

}