【问题标题】:Why would FifoFixer's `stall` signal go high forever?为什么 FifoFixer 的“失速”信号会永远变高?
【发布时间】:2022-07-23 12:07:48
【问题描述】:

我正在尝试通过前端总线将这些相当大的 DMA 传输到内存。前端总线已准备就绪此时没有其他客户端在争夺前端总线。我在第 15 次 2kB 传输中连接的 AXI 客户端无法完成传输,因为FifoFixer 的停顿信号变高并且永远不会下降。我正在努力,希望有人能帮助我理解以下代码行(以及其他外交小部件),以了解为什么 stall 变高,AXI 客户端的 wready 信号变低,以及交易永远不会完成。

      val stalls = edgeIn.client.clients.filter(c => c.requestFifo && c.sourceId.size > 1).map { c =>
        val a_sel = c.sourceId.contains(in.a.bits.source)
        val id    = RegEnable(a_id, in.a.fire() && a_sel && !a_notFIFO)
        val track = flight.slice(c.sourceId.start, c.sourceId.end)

        a_sel && a_first && track.reduce(_ || _) && (a_noDomain || id =/= a_id)
      }

      val stall = stalls.foldLeft(Bool(false))(_||_)

对于每个 w 通道传输,awaddr 通道握手使用相同的 aw 通道 ID。 Tilelink A 通道握手发生在前 64 个字节,然后 a_ready 信号永远变低,即使前端总线和 FifoFixer 正在接收 a_ready 高信号。

我的外交小部件连接:

    ( dmaDDRNode 
        := TLBuffer(BufferParams.default)
        // := TLFIFOFixer(TLFIFOFixer.all) // included in fromPort
        := TLWidthWidget(8)
        := AXI4ToTL()
        := AXI4UserYanker(capMaxFlight=Some(16)) // Might want to cap max flight # but I don't know what that cap should be - ME
        := AXI4Fragmenter()
        := AXI4IdIndexer(idBits=3)
        // := AXI4Buffer()
        := dmaTop.ddrMaster)

fbus.fromPort(Some("DMA_DDR_MASTER"))() := dmaDDRNode 

我怀疑它可能是使用wready 来确定下一个wvalid 的DMA 引擎?这可能违反一些解耦假设。这可能与 capMaxFlight 为 16 岁有关,但通过前总线完成的所有其他传输。

【问题讨论】:

    标签: chisel rocket-chip


    【解决方案1】:

    FifoFixer 确保 Put 操作的 d_source 在开始下一个 A 通道传输之前完成。因此,在屏幕截图(来源'hf)中发送传输后,它等待d 通道为'hf 提供确认。前面总线上的 d 通道似乎已经停止,因为 TL 客户端之一将d_ready 拉低了。与此 TL 客户端关联的 AXI 主机在请求读取后将其 r_ready 保持为低电平,因此 FifoFixer 将 stall 保持为高电平。

    虽然 DAG 属性可确保无死锁操作,但它无法阻止两个源节点在彼此之间创建“虚拟”连接。在我的例子中,一个 AXI 源节点请求的数据依赖于另一个 AXI 源节点完成其请求。这破坏了 DAG 属性并造成了死锁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-15
      • 2020-04-08
      • 2019-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多