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))
}