Что означает, что «Q должен быть готов быстрее, чем ответ» для утверждения Янкера пользователя AXI4?

Я пытаюсь выполнить DMA, в котором мастер AXI получает выборку из подчиненного устройства AXI. Для простоты я решил подключить эту систему через переднюю шину TL и системную шину, а не напрямую друг с другом, поскольку другим мастерам может потребоваться доступ к ведомому устройству AXI. Я использую порт MMIO по умолчанию для Rocket Chip. Я вызвал его с помощью следующих 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 извлекаются из очереди, и перед установкой битов канала in b мы проверяем это утверждение. Я до сих пор не совсем понимаю, что это значит. Мое лучшее предположение: b.valid становится высоким до того, как у UserYanker появится место в очереди? Означает ли это, что мне нужны очереди большего размера? Если это так, какой параметр увеличит размер очереди UserYanker? Будет ли это maxFlight? Это какая-то проблема с трансляцией протокола с Tilelink на axi4? Я не знаком с их спецификой, но, может быть, в этом случае следует пропустить преобразование в Tilelink?

0 ответов

Другие вопросы по тегам