0

我正在尝试执行涉及从 AXI 从站获取 AXI 主站的 DMA。为简单起见,我选择通过 TL 前端总线和系统总线而不是直接相互连接该系统,因为其他主机可能需要访问 AXI 从机。我正在使用 Rocket Chip 的默认 MMIO 端口。我已经使用以下 MasterPortParams 调用了它。

class WithMMIOPort extends Config((site, here, up) => {
  case ExtBus => Some(MasterPortParams(
                      base = x"4000_0000",
                      size = x"2000_0000",
                      beatBytes = site(MemoryBusKey).beatBytes,
                      idBits = 4))
})

这是MMIO端口供参考。

trait CanHaveMasterAXI4MMIOPort { this: BaseSubsystem =>
  private val mmioPortParamsOpt = p(ExtBus)
  private val portName = "mmio_port_axi4"
  private val device = new SimpleBus(portName.kebab, Nil)

  val mmioAXI4Node = AXI4SlaveNode(
    mmioPortParamsOpt.map(params =>
      AXI4SlavePortParameters(
        slaves = Seq(AXI4SlaveParameters(
          address       = AddressSet.misaligned(params.base, params.size),
          resources     = device.ranges,
          executable    = params.executable,
          supportsWrite = TransferSizes(1, params.maxXferBytes),
          supportsRead  = TransferSizes(1, params.maxXferBytes))),
        beatBytes = params.beatBytes)).toSeq)

  mmioPortParamsOpt.map { params =>
    sbus.coupleTo(s"port_named_$portName") {
      (mmioAXI4Node
        := AXI4Buffer()
        := AXI4UserYanker()
        := AXI4Deinterleaver(sbus.blockBytes)
        := AXI4IdIndexer(params.idBits)
        := TLToAXI4()
        := TLWidthWidget(sbus.beatBytes)
        := _)
    }
  }

这是试图发出写入的主节点。

(dmaHstNode          
        := TLBuffer(BufferParams.default)
        // := TLFIFOFixer(TLFIFOFixer.all)
        := TLWidthWidget(8) 
        := AXI4ToTL()
        := AXI4UserYanker(capMaxFlight=Some(16))
        := AXI4Fragmenter()
        := AXI4IdIndexer(idBits=3)
        := AXI4Buffer()
        := dmaTop.hstMaster)
        // }

它开始发出写入,但随后我遇到断言失败 assert (!out.b.valid || b_valid) // Q must be ready faster than the response

我试图理解这个断言的含义。它来自 UserYanker。这是在上下文中

 val bid = out.b.bits.id
      val b_valid = Vec(wqueues.map(_.deq.valid))(bid)
      val b_bits = Vec(wqueues.map(_.deq.bits))(bid)
      assert (!out.b.valid || b_valid) // Q must be ready faster than the response
      in.b :<> out.b
      in.b.bits.echo :<= b_bits

b_bits 从队列中取出,在设置 b 通道位之前,我们检查这个断言。我仍然不太确定这意味着什么。我最好的猜测是在 UserYanker 的队列中有空间之前 b.valid 会变高吗?这是否意味着我需要更大的队列?如果是这种情况,什么参数会增加 UserYanker 的队列大小?会是maxFlight吗?这是从 Tilelink 到 axi4 的某种协议转换问题吗?我对两者的细节都不熟悉,但在这种情况下可能应该跳过到 Tilelink 的转换?

4

0 回答 0