SpinalHDL AXI相关bus简单转换示例

1.下载SpinalHDL templet工程

2.配置build.sbt

ThisBuild / version := "1.0"
ThisBuild / scalaVersion := "2.11.12"
ThisBuild / organization := "org.example"

val spinalVersion = "1.9.1"
val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion
val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion
val spinalIdslPlugin = compilerPlugin("com.github.spinalhdl" %% "spinalhdl-idsl-plugin" % spinalVersion)

lazy val projectname = (project in file("."))
  .settings(
    Compile / scalaSource := baseDirectory.value / "hw" / "spinal",
    libraryDependencies ++= Seq(spinalCore, spinalLib, spinalIdslPlugin)
  )

fork := true

3.配置Config

package projectname

import spinal.core._
import spinal.core.sim._

object Config {
  def spinal = SpinalConfig(
    targetDirectory = "hw/gen",
    defaultConfigForClockDomains = ClockDomainConfig(
      resetActiveLevel = HIGH
    ),
    onlyStdLogicVectorAtTopLevelIo = true
  )

  def sim = SimConfig.withConfig(spinal).withFstWave
}

4.bus转换示例

package projectname

import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.amba4.axilite._
import spinal.lib.bus.amba4.axilite.AxiLite4Utils.Axi4Rich
import spinal.lib.bus.misc.SizeMapping
import javax.swing.text.FlowView

// -------------------------------------------

case class Axi42AxiLite4() extends Component {

  val config = Axi4Config(
    addressWidth = 48,
    dataWidth    = 512,
    idWidth      = 4
  )

  val io = new Bundle {
    val axi = slave(Axi4(config))
    val axilite = master(AxiLite4(AxiLite4Config(addressWidth = config.addressWidth, dataWidth = config.dataWidth)))
  }

  io.axi.toLite() >> io.axilite

}

// -------------------------------------------

case class TwoAxi42AxiLite4() extends Component {

  val masterConfig = Axi4Config(
    addressWidth = 48,
    dataWidth    = 512,
    idWidth      = 4,
    useRegion    = false,
    useQos       = false
  )
  val slaveConfig = masterConfig.copy(idWidth = 5)

  val io = new Bundle {
    val axi = Vec(slave(Axi4(masterConfig)), size = 2)
    val axilite = master(AxiLite4(AxiLite4Config(addressWidth = masterConfig.addressWidth, dataWidth = masterConfig.dataWidth)))
    axi.foreach(Axi4SpecRenamer(_))
  }

  noIoPrefix()

  val tmp_axi = Axi4(slaveConfig)

  val axiCrossBar = Axi4CrossbarFactory()
  axiCrossBar.addSlaves((tmp_axi, SizeMapping(0, 256 TiB)))
  io.axi.foreach(axiCrossBar.addConnection(_, Vec(tmp_axi, 1)))
  axiCrossBar.addPipelining(tmp_axi)(
    (masterPort, slavePort) => {
      masterPort.ar >-> slavePort.ar
      slavePort.r >-> masterPort.r
    }
  ) (
    (masterPort, slavePort) => {
      masterPort.aw >-> slavePort.aw
      masterPort.w >-> slavePort.w
      slavePort.b >-> masterPort.b
    }
  )
  axiCrossBar.build()

  tmp_axi.toLite() >> io.axilite

}

// -------------------------------------------

case class FourAxi42OneAxi() extends Component {

  val inConfig = Axi4Config(
    addressWidth = 32,
    dataWidth    = 512,
    idWidth      = 8,
    useRegion    = false,
    useQos       = false
  )
  val outConfig = inConfig.copy(idWidth = inConfig.idWidth + 2)

  val io = new Bundle {
    val axiIn = Vec(slave(Axi4(inConfig)), size = 4)
    val axiOut = master(Axi4(outConfig))
    axiIn.foreach(Axi4SpecRenamer(_))
    Axi4SpecRenamer(axiOut)
  }

  noIoPrefix()

  val axiCrossBar = Axi4CrossbarFactory()
  axiCrossBar.addSlaves((io.axiOut, SizeMapping(0, 4 GiB)))
  io.axiIn.foreach(axiCrossBar.addConnection(_, Vec(io.axiOut, 1)))
  axiCrossBar.addPipelining(io.axiOut)(
    (masterPort, slavePort) => {
      masterPort.ar >-> slavePort.ar
      slavePort.r >-> masterPort.r
    }
  ) (
    (masterPort, slavePort) => {
      masterPort.aw >-> slavePort.aw
      masterPort.w >-> slavePort.w
      slavePort.b >-> masterPort.b
    }
  )
  axiCrossBar.build()

}

// -------------------------------------------

case class FourAxiLite42OneAxiLite4() extends Component {

  val Config = AxiLite4Config(
    addressWidth = 32,
    dataWidth    = 32
  )

  val io = new Bundle {
    val inAxilite4 = Vec(slave(AxiLite4(Config)), size = 4)
    val localWrite = master(Stream(Bits(Config.addressWidth+Config.dataWidth bits)))
    val localReadCmd = master(Stream(Bits(Config.addressWidth bits)))
    val localReadAck = slave(Stream(Bits(Config.dataWidth bits)))
    inAxilite4.foreach(AxiLite4SpecRenamer(_))
  }

  noIoPrefix()

}

// -------------------------------------------

object xxm extends App {

  Config.spinal.generateSystemVerilog(FourAxi42OneAxi())
}

5.位宽转换示例

package projectname

import spinal.core._
import spinal.lib._
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.amba4.axi.Axi4Downsizer
import spinal.lib.bus.amba4.axilite._
import spinal.lib.bus.amba4.axilite.AxiLite4Utils.Axi4Rich
import spinal.lib.bus.misc.SizeMapping
import javax.swing.text.FlowView

// -------------------------------------------

case class spiHDL_AxiDownsizer() extends Component {

  val inConfig = Axi4Config(
    addressWidth = 33,
    dataWidth    = 512,
    idWidth      = 6
  )
  val outConfig = inConfig.copy(dataWidth = inConfig.dataWidth / 2)

  val io = new Bundle {
    val axiIn = slave(Axi4(inConfig))
    val axiOut = master(Axi4(outConfig))
    Axi4SpecRenamer(axiIn)
    Axi4SpecRenamer(axiOut)
  }

  noIoPrefix()

  val axi4_downsizer_inst = Axi4Downsizer(inConfig, outConfig)
  io.axiIn >> axi4_downsizer_inst.io.input
  axi4_downsizer_inst.io.output >> io.axiOut

}

// -------------------------------------------

object MyAxiDownsizer extends App {

  Config.spinal.generateSystemVerilog(spiHDL_AxiDownsizer())
}

实现将AXI4协议数据转换AXI-Stream协议数据的过程可以通过以下步骤进行: 1. AXI4协议数据格式(如地址、数据、控制信号等)与AXI-Stream协议数据格式(仅有数据信号)存在差异,在转换过程中需要对数据进行重新组织和调整。 2. 首先,从AXI4总线上接收到的数据包括地址信号、数据信号和控制信号。其中,地址信号指示要访问的AXI4设备的具体位置,数据信号包含要传输的实际数据,而控制信号则指示操作类型和传输方向。 3. 在数据转换模块中,需要将接收到的AXI4数据进行解析和分离。根据AXI4协议规范,地址信号和数据信号以及控制信号之间存在对应关系。通过解析控制信号,可以确定要进行的操作类型,如读取或写入。 4. 根据控制信号的类型(读取或写入),确定在AXI-Stream数据中要设置的有效位(Valid)标志。对于写入操作,需要将有效位设置为高电平,以指示有新的数据要传输。对于读取操作,有效位设置为低电平,以指示无新的数据传输。 5. 组织被选中的数据(根据控制信号的读取或写入操作类型),并以AXI-Stream协议的格式进行处理和编码。AXI-Stream协议仅包含数据信号,没有地址信号和控制信号。 6. 在AXI-Stream数据中,根据AXI4数据的信息,包含数据位(data)以及标志位(valid)。有效位标志(valid)在数据有效时设置为高电平,以表明数据位(data)是有效的。 7. 最后,将转换后的AXI-Stream数据发送到AXI-Stream总线上,以供其他支持该协议的设备使用。 通过以上步骤,可以将AXI4协议数据转换AXI-Stream协议数据,实现不同协议之间的数据交互和传输。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值