APB3定义

简介

此示例将展示定义一个APB3 Bundle 的语句。

规范

ARM关于APB3的端口规范如下:

信号名称

类型

驱动端

描述

PADDR

UInt(addressWidth bits)

Master

以字节为单位的地址

PSEL

Bits(selWidth)

Master

每个从端1bit

PENABLE

Bool

Master

PWRITE

Bool

Master

PWDATA

Bits(dataWidth bits)

Master

PREADY

Bool

Slave

PRDATA

Bits(dataWidth bits)

Slave

PSLVERROR

Bool

Slave

可选

实现

该规范表明APB3总线具有多种可能的配置。为了实现这一点,我们可以在Scala中定义一个配置类:

case class Apb3Config(
  addressWidth: Int,
  dataWidth: Int,
  selWidth: Int = 1,
  useSlaveError: Boolean = true
)

然后我们可以定义用于表示硬件总线的APB3 Bundle

case class Apb3(config: Apb3Config) extends Bundle with IMasterSlave {
  val PADDR = UInt(config.addressWidth bits)
  val PSEL = Bits(config.selWidth bits)
  val PENABLE = Bool()
  val PREADY = Bool()
  val PWRITE = Bool()
  val PWDATA = Bits(config.dataWidth bits)
  val PRDATA = Bits(config.dataWidth bits)
  val PSLVERROR  = if(config.useSlaveError) Bool() else null

  override def asMaster(): Unit = {
    out(PADDR,PSEL,PENABLE,PWRITE,PWDATA)
    in(PREADY,PRDATA)
    if(config.useSlaveError) in(PSLVERROR)
  }
}

用法

以下是该定义的用法示例:

case class Apb3User(apbConfig: Apb3Config) extends Component {
  val io = new Bundle {
    val apb = slave(Apb3(apbConfig))
  }

  io.apb.PREADY := True
  when(io.apb.PSEL(0) && io.apb.PENABLE) {
    // ...
  }

  io.apb.PRDATA := B(0)
}

object Apb3User extends App {
  val config = Apb3Config(
    addressWidth = 16,
    dataWidth = 32,
    selWidth = 1,
    useSlaveError = false
  )
  SpinalVerilog(Apb3User(config))
}